Search in sources :

Example 36 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class FunMatches method evalWithIndex.

/**
 * @param contextSequence the context sequence
 * @param contextItem the context item
 * @param input the value of the $input arg
 * @return The resulting sequence
 * @throws XPathException if an error occurs
 */
private Sequence evalWithIndex(final Sequence contextSequence, final Item contextItem, final Sequence input) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    final int flags;
    if (getSignature().getArgumentCount() == 3) {
        final String flagsArg = getArgument(2).eval(contextSequence, contextItem).getStringValue();
        flags = parseFlags(this, flagsArg);
    } else {
        flags = 0;
    }
    final boolean caseSensitive = !hasCaseInsensitive(flags);
    Sequence result = null;
    final String pattern;
    if (isCalledAs("matches-regex")) {
        pattern = getArgument(1).eval(contextSequence, contextItem).getStringValue();
    } else {
        final boolean literal = hasLiteral(flags);
        if (literal) {
            // no need to change anything
            pattern = getArgument(1).eval(contextSequence, contextItem).getStringValue();
        } else {
            final boolean ignoreWhitespace = hasIgnoreWhitespace(flags);
            final boolean caseBlind = !caseSensitive;
            pattern = translateRegexp(this, getArgument(1).eval(contextSequence, contextItem).getStringValue(), ignoreWhitespace, caseBlind);
        }
    }
    final NodeSet nodes = input.toNodeSet();
    // get the type of a possible index
    final int indexType = nodes.getIndexType();
    if (LOG.isTraceEnabled()) {
        LOG.trace("found an index of type: {}", Type.getTypeName(indexType));
    }
    if (Type.subTypeOf(indexType, Type.STRING)) {
        boolean indexScan = false;
        if (contextSequence != null) {
            final GeneralComparison.IndexFlags iflags = GeneralComparison.checkForQNameIndex(idxflags, context, contextSequence, contextQName);
            boolean indexFound = false;
            if (!iflags.indexOnQName()) {
                // if contextQName != null and no index is defined on
                // contextQName, we don't need to scan other QName indexes
                // and can just use the generic range index
                indexFound = contextQName != null;
                // set contextQName to null so the index lookup below is not
                // restricted to that QName
                contextQName = null;
            }
            if (!indexFound && contextQName == null) {
                // we need to check them all
                if (iflags.hasIndexOnQNames()) {
                    indexScan = true;
                }
            // else use range index defined on path by default
            }
        } else {
            result = evalFallback(nodes, pattern, flags, indexType);
        }
        if (result == null) {
            final DocumentSet docs = nodes.getDocumentSet();
            try {
                final NativeValueIndex index = context.getBroker().getValueIndex();
                hasUsedIndex = true;
                // TODO : check index' case compatibility with flags' one ? -pb
                if (context.isProfilingEnabled()) {
                    context.getProfiler().message(this, Profiler.OPTIMIZATIONS, "Using value index '" + index.toString() + "'", "Regex: " + pattern);
                }
                if (LOG.isTraceEnabled()) {
                    LOG.trace("Using range index for fn:matches expression: {}", pattern);
                }
                if (indexScan) {
                    result = index.matchAll(context.getWatchDog(), docs, nodes, NodeSet.ANCESTOR, pattern, DBBroker.MATCH_REGEXP, flags, caseSensitive);
                } else {
                    result = index.match(context.getWatchDog(), docs, nodes, NodeSet.ANCESTOR, pattern, contextQName, DBBroker.MATCH_REGEXP, flags, caseSensitive);
                }
            } catch (final EXistException e) {
                throw new XPathException(this, e);
            }
        }
    } else {
        result = evalFallback(nodes, pattern, flags, indexType);
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) NativeValueIndex(org.exist.storage.NativeValueIndex) Sequence(org.exist.xquery.value.Sequence) DocumentSet(org.exist.dom.persistent.DocumentSet) EXistException(org.exist.EXistException)

Example 37 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class FunNot method eval.

public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    Sequence result;
    final Expression arg = getArgument(0);
    // the remaining set
    if (Type.subTypeOf(arg.returnsType(), Type.NODE) && (contextSequence == null || contextSequence.isPersistentSet()) && !Dependency.dependsOn(arg, Dependency.CONTEXT_ITEM)) {
        if (contextSequence == null || contextSequence.isEmpty()) {
            // TODO: special treatment if the context sequence is empty:
            // within a predicate, we just return the empty sequence
            // otherwise evaluate the argument and return a boolean result
            // if (inPredicate && !inWhereClause)
            // result = Sequence.EMPTY_SEQUENCE;
            // else
            result = evalBoolean(contextSequence, contextItem, arg);
        } else {
            result = contextSequence.toNodeSet().copy();
            if (inPredicate) {
                for (final SequenceIterator i = result.iterate(); i.hasNext(); ) {
                    final NodeProxy item = (NodeProxy) i.nextItem();
                    // item.addContextNode(getExpressionId(), item);
                    if (contextId != Expression.NO_CONTEXT_ID) {
                        item.addContextNode(contextId, item);
                    } else {
                        item.addContextNode(getExpressionId(), item);
                    }
                }
            }
            // evaluate argument expression
            final Sequence argSeq = arg.eval(result);
            NodeSet argSet;
            if (contextId != Expression.NO_CONTEXT_ID) {
                argSet = argSeq.toNodeSet().getContextNodes(contextId);
            } else {
                argSet = argSeq.toNodeSet().getContextNodes(getExpressionId());
            }
            result = ((NodeSet) result).except(argSet);
        }
    // case 2: simply invert the boolean value
    } else {
        return evalBoolean(contextSequence, contextItem, arg);
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) SequenceIterator(org.exist.xquery.value.SequenceIterator) Expression(org.exist.xquery.Expression) Sequence(org.exist.xquery.value.Sequence) NodeProxy(org.exist.dom.persistent.NodeProxy)

Example 38 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class LocalXPathQueryService method query.

@Override
public ResourceSet query(final XMLResource res, final String query, final String sortBy) throws XMLDBException {
    final Node n = ((LocalXMLResource) res).root;
    return withDb((broker, transaction) -> {
        if (n != null && n instanceof org.exist.dom.memtree.NodeImpl) {
            final XmldbURI[] docs = new XmldbURI[] { getCollectionUri(broker, transaction, res.getParentCollection()) };
            return doQuery(broker, transaction, query, docs, (org.exist.dom.memtree.NodeImpl) n, sortBy);
        }
        final NodeProxy node = ((LocalXMLResource) res).getNode(broker, transaction);
        if (node == null) {
            // resource is a document
            // TODO : use dedicated function in XmldbURI
            final XmldbURI[] docs = new XmldbURI[] { getCollectionUri(broker, transaction, res.getParentCollection()).append(res.getDocumentId()) };
            return doQuery(broker, transaction, query, docs, null, sortBy);
        } else {
            final NodeSet set = new ExtArrayNodeSet(1);
            set.add(node);
            final XmldbURI[] docs = new XmldbURI[] { node.getOwnerDocument().getURI() };
            return doQuery(broker, transaction, query, docs, set, sortBy);
        }
    });
}
Also used : ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) Node(org.w3c.dom.Node) NodeProxy(org.exist.dom.persistent.NodeProxy)

Example 39 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class LocalXPathQueryService method execute.

@Override
public ResourceSet execute(final XMLResource res, final CompiledExpression expression) throws XMLDBException {
    return withDb((broker, transaction) -> {
        final NodeProxy node = ((LocalXMLResource) res).getNode(broker, transaction);
        if (node == null) {
            // resource is a document
            final XmldbURI[] docs = new XmldbURI[] { getCollectionUri(broker, transaction, res.getParentCollection()).append(res.getDocumentId()) };
            return execute(broker, transaction, docs, null, expression, null);
        } else {
            final NodeSet set = new ExtArrayNodeSet(1);
            set.add(node);
            final XmldbURI[] docs = new XmldbURI[] { node.getOwnerDocument().getURI() };
            return execute(broker, transaction, docs, set, expression, null);
        }
    });
}
Also used : ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeProxy(org.exist.dom.persistent.NodeProxy)

Example 40 with NodeSet

use of org.exist.dom.persistent.NodeSet in project exist by eXist-db.

the class IndexKeyDocuments method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
    }
    Sequence result;
    if (args[0].isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        final NodeSet nodes = args[0].toNodeSet();
        final DocumentSet docs = nodes.getDocumentSet();
        if (this.getArgumentCount() == 3) {
            final IndexWorker indexWorker = context.getBroker().getIndexController().getWorkerByIndexName(args[2].itemAt(0).getStringValue());
            // IndexWorker indexWorker = context.getBroker().getBrokerPool().getIndexManager().getIndexByName(args[2].itemAt(0).getStringValue()).getWorker();
            if (indexWorker == null) {
                throw new XPathException(this, "Unknown index: " + args[2].itemAt(0).getStringValue());
            }
            final Map<String, Object> hints = new HashMap<>();
            if (indexWorker instanceof OrderedValuesIndex) {
                hints.put(OrderedValuesIndex.START_VALUE, args[1]);
            } else {
                logger.warn("{} isn't an instance of org.exist.indexing.OrderedIndexWorker. Start value '{}' ignored.", indexWorker.getClass().getName(), args[1]);
            }
            final Occurrences[] occur = indexWorker.scanIndex(context, docs, nodes, hints);
            if (occur.length == 0) {
                result = Sequence.EMPTY_SEQUENCE;
            } else {
                result = new IntegerValue(occur[0].getDocuments());
            }
        } else {
            final ValueOccurrences[] occur = context.getBroker().getValueIndex().scanIndexKeys(docs, nodes, (Indexable) args[1]);
            if (occur.length == 0) {
                result = Sequence.EMPTY_SEQUENCE;
            } else {
                result = new IntegerValue(occur[0].getDocuments());
            }
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) XPathException(org.exist.xquery.XPathException) HashMap(java.util.HashMap) IntegerValue(org.exist.xquery.value.IntegerValue) ValueOccurrences(org.exist.util.ValueOccurrences) OrderedValuesIndex(org.exist.indexing.OrderedValuesIndex) Occurrences(org.exist.util.Occurrences) ValueOccurrences(org.exist.util.ValueOccurrences) Sequence(org.exist.xquery.value.Sequence) IndexWorker(org.exist.indexing.IndexWorker) DocumentSet(org.exist.dom.persistent.DocumentSet)

Aggregations

NodeSet (org.exist.dom.persistent.NodeSet)49 NodeProxy (org.exist.dom.persistent.NodeProxy)18 Sequence (org.exist.xquery.value.Sequence)18 DocumentSet (org.exist.dom.persistent.DocumentSet)14 NewArrayNodeSet (org.exist.dom.persistent.NewArrayNodeSet)12 QName (org.exist.dom.QName)11 ExtArrayNodeSet (org.exist.dom.persistent.ExtArrayNodeSet)10 VirtualNodeSet (org.exist.dom.persistent.VirtualNodeSet)9 ContextItem (org.exist.dom.persistent.ContextItem)8 IOException (java.io.IOException)7 XPathException (org.exist.xquery.XPathException)7 Collator (com.ibm.icu.text.Collator)4 EXistException (org.exist.EXistException)4 DocumentImpl (org.exist.dom.persistent.DocumentImpl)4 EmptyNodeSet (org.exist.dom.persistent.EmptyNodeSet)4 Indexable (org.exist.storage.Indexable)4 SequenceIterator (org.exist.xquery.value.SequenceIterator)4 StringValue (org.exist.xquery.value.StringValue)4 NodeImpl (org.exist.dom.memtree.NodeImpl)3 Match (org.exist.dom.persistent.Match)3