Search in sources :

Example 1 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class GeneralComparison method preSelect.

public NodeSet preSelect(Sequence contextSequence, boolean useContext) throws XPathException {
    // the expression can be called multiple times, so we need to clear the previous preselectResult
    preselectResult = null;
    final long start = System.currentTimeMillis();
    final int indexType = Optimize.getQNameIndexType(context, contextSequence, contextQName);
    if (LOG.isTraceEnabled()) {
        LOG.trace("Using QName index on type {}", Type.getTypeName(indexType));
    }
    final Sequence rightSeq = getRight().eval(contextSequence);
    // into preselectResult
    if (rightSeq.getItemCount() > 1) {
        preselectResult = new NewArrayNodeSet();
    }
    // Iterate through each item in the right-hand sequence
    for (final SequenceIterator itRightSeq = Atomize.atomize(rightSeq).iterate(); itRightSeq.hasNext(); ) {
        // Get the index key
        Item key = itRightSeq.nextItem();
        // if key has truncation, convert it to string
        if (truncation != StringTruncationOperator.NONE) {
            if (!Type.subTypeOf(key.getType(), Type.STRING)) {
                LOG.info("Truncated key. Converted from {} to xs:string", Type.getTypeName(key.getType()));
                // truncation is only possible on strings
                key = key.convertTo(Type.STRING);
            }
        } else // TODO : use Type.isSubType() ??? -pb
        if (key.getType() != indexType) {
            // try to convert the key to the index type
            try {
                key = key.convertTo(indexType);
            } catch (final XPathException xpe) {
                if (LOG.isTraceEnabled()) {
                    LOG.trace("Cannot convert key: {} to required index type: {}", Type.getTypeName(key.getType()), Type.getTypeName(indexType));
                }
                throw (new XPathException(this, "Cannot convert key to required index type"));
            }
        }
        // If key implements org.exist.storage.Indexable, we can use the index
        if (key instanceof Indexable) {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Using QName range index for key: {}", key.getStringValue());
            }
            NodeSet temp;
            final NodeSet contextSet = useContext ? contextSequence.toNodeSet() : null;
            final Collator collator = ((collationArg != null) ? getCollator(contextSequence) : null);
            if (truncation == StringTruncationOperator.NONE) {
                temp = context.getBroker().getValueIndex().find(context.getWatchDog(), relation, contextSequence.getDocumentSet(), contextSet, NodeSet.DESCENDANT, contextQName, (Indexable) key);
                hasUsedIndex = true;
            } else {
                try {
                    final String matchString = key.getStringValue();
                    final int matchType = getMatchType(truncation);
                    temp = context.getBroker().getValueIndex().match(context.getWatchDog(), contextSequence.getDocumentSet(), contextSet, NodeSet.DESCENDANT, matchString, contextQName, matchType, collator, truncation);
                    hasUsedIndex = true;
                } catch (final EXistException e) {
                    throw (new XPathException(this, "Error during index lookup: " + e.getMessage(), e));
                }
            }
            // else replace it.
            if (preselectResult == null) {
                preselectResult = temp;
            } else {
                preselectResult.addAll(temp);
            }
        }
    }
    if (context.getProfiler().traceFunctions()) {
        context.getProfiler().traceIndexUsage(context, PerformanceStats.RANGE_IDX_TYPE, this, PerformanceStats.OPTIMIZED_INDEX, System.currentTimeMillis() - start);
    }
    return ((preselectResult == null) ? NodeSet.EMPTY_SET : preselectResult);
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) Item(org.exist.xquery.value.Item) ContextItem(org.exist.dom.persistent.ContextItem) SequenceIterator(org.exist.xquery.value.SequenceIterator) Indexable(org.exist.storage.Indexable) Sequence(org.exist.xquery.value.Sequence) EXistException(org.exist.EXistException) Collator(com.ibm.icu.text.Collator)

Example 2 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class OpNumeric 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());
        }
    }
    final Sequence lseq = Atomize.atomize(getLeft().eval(contextSequence, contextItem));
    final Sequence rseq = Atomize.atomize(getRight().eval(contextSequence, contextItem));
    if (lseq.hasMany()) {
        throw new XPathException(this, ErrorCodes.XPTY0004, "Too many operands at the left of " + operator.symbol);
    }
    if (rseq.hasMany()) {
        throw new XPathException(this, ErrorCodes.XPTY0004, "Too many operands at the right of " + operator.symbol);
    }
    Sequence result;
    if (rseq.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else if (lseq.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        Item lvalue = lseq.itemAt(0);
        Item rvalue = rseq.itemAt(0);
        try {
            if (lvalue.getType() == Type.UNTYPED_ATOMIC || lvalue.getType() == Type.ATOMIC) {
                lvalue = lvalue.convertTo(Type.NUMBER);
            }
            if (rvalue.getType() == Type.UNTYPED_ATOMIC || rvalue.getType() == Type.ATOMIC) {
                rvalue = rvalue.convertTo(Type.NUMBER);
            }
            if (!(lvalue instanceof ComputableValue)) {
                throw new XPathException(this, ErrorCodes.XPTY0004, "'" + Type.getTypeName(lvalue.getType()) + "(" + lvalue + ")' can not be an operand for " + operator.symbol);
            }
            if (!(rvalue instanceof ComputableValue)) {
                throw new XPathException(this, ErrorCodes.XPTY0004, "'" + Type.getTypeName(rvalue.getType()) + "(" + rvalue + ")' can not be an operand for " + operator.symbol);
            }
            // TODO : move to implementations
            if (operator == ArithmeticOperator.DIVISION_INTEGER) {
                if (!Type.subTypeOfUnion(lvalue.getType(), Type.NUMBER)) {
                    throw new XPathException(this, ErrorCodes.XPTY0004, "'" + Type.getTypeName(lvalue.getType()) + "(" + lvalue + ")' can not be an operand for " + operator.symbol);
                }
                if (!Type.subTypeOfUnion(rvalue.getType(), Type.NUMBER)) {
                    throw new XPathException(this, ErrorCodes.XPTY0004, "'" + Type.getTypeName(rvalue.getType()) + "(" + rvalue + ")' can not be an operand for " + operator.symbol);
                }
                // If the divisor is (positive or negative) zero, then an error is raised [err:FOAR0001]
                if (((NumericValue) rvalue).isZero()) {
                    throw new XPathException(this, ErrorCodes.FOAR0001, "Division by zero");
                }
                // If either operand is NaN then an error is raised [err:FOAR0002].
                if (((NumericValue) lvalue).isNaN()) {
                    throw new XPathException(this, ErrorCodes.FOAR0002, "Division of " + Type.getTypeName(lvalue.getType()) + "(" + lvalue + ")'");
                }
                // If either operand is NaN then an error is raised [err:FOAR0002].
                if (((NumericValue) rvalue).isNaN()) {
                    throw new XPathException(this, ErrorCodes.FOAR0002, "Division of " + Type.getTypeName(rvalue.getType()) + "(" + rvalue + ")'");
                }
                // If $arg1 is INF or -INF then an error is raised [err:FOAR0002].
                if (((NumericValue) lvalue).isInfinite()) {
                    throw new XPathException(this, ErrorCodes.FOAR0002, "Division of " + Type.getTypeName(lvalue.getType()) + "(" + lvalue + ")'");
                }
                result = ((NumericValue) lvalue).idiv((NumericValue) rvalue);
            } else {
                result = applyOperator((ComputableValue) lvalue, (ComputableValue) rvalue);
            }
        // TODO : type-checks on MOD operator : maybe the same ones than above -pb
        } catch (final XPathException e) {
            e.setLocation(line, column);
            throw e;
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    // Sets the return type if not already set
    if (returnType == Type.ATOMIC) // TODO : refine previously set type ? -pb
    {
        returnType = result.getItemType();
    }
    return result;
}
Also used : Item(org.exist.xquery.value.Item) ComputableValue(org.exist.xquery.value.ComputableValue) Sequence(org.exist.xquery.value.Sequence) NumericValue(org.exist.xquery.value.NumericValue)

Example 3 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class XMLDBAbstractCollectionManipulator method eval.

@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
    if (0 == args.length) {
        throw new XPathException(this, "Expected a collection as the argument " + (paramNumber + 1) + ".");
    }
    final boolean collectionNeedsClose = false;
    Collection collection = null;
    final Item item = args[paramNumber].itemAt(0);
    if (Type.subTypeOf(item.getType(), Type.NODE)) {
        final NodeValue node = (NodeValue) item;
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Found node");
        }
        if (node.getImplementationType() == NodeValue.PERSISTENT_NODE) {
            final org.exist.collections.Collection internalCol = ((NodeProxy) node).getOwnerDocument().getCollection();
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Found node");
            }
            try {
                // TODO: use xmldbURI
                collection = getLocalCollection(context, internalCol.getURI().toString());
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Loaded collection {}", collection.getName());
                }
            } catch (final XMLDBException e) {
                throw new XPathException(this, "Failed to access collection: " + internalCol.getURI(), e);
            }
        } else {
            return Sequence.EMPTY_SEQUENCE;
        }
    }
    if (collection == null) {
        // Otherwise, just extract the name as a string:
        final String collectionURI = args[paramNumber].getStringValue();
        if (collectionURI != null) {
            try {
                collection = getCollection(context, collectionURI, Optional.empty(), Optional.empty());
            } catch (final XMLDBException xe) {
                if (errorIfAbsent) {
                    throw new XPathException(this, "Could not locate collection: " + collectionURI, xe);
                }
                collection = null;
            }
        }
        if (collection == null && errorIfAbsent) {
            throw new XPathException(this, "Unable to find collection: " + collectionURI);
        }
    }
    Sequence s = Sequence.EMPTY_SEQUENCE;
    try {
        s = evalWithCollection(collection, args, contextSequence);
    } finally {
        if (collectionNeedsClose && collection != null) {
            try {
                collection.close();
            } catch (final Exception e) {
                throw new XPathException(this, "Unable to close collection", e);
            }
        }
    }
    return s;
}
Also used : Item(org.exist.xquery.value.Item) NodeValue(org.exist.xquery.value.NodeValue) XPathException(org.exist.xquery.XPathException) InTxnLocalCollection(org.exist.xmldb.txn.bridge.InTxnLocalCollection) LocalCollection(org.exist.xmldb.LocalCollection) Collection(org.xmldb.api.base.Collection) XMLDBException(org.xmldb.api.base.XMLDBException) Sequence(org.exist.xquery.value.Sequence) XMLDBException(org.xmldb.api.base.XMLDBException) XPathException(org.exist.xquery.XPathException)

Example 4 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class Shared method getUrls.

/**
 * Get URL values of sequence items.
 *
 * @param s Sequence
 * @return URLs of items in sequence
 * @throws XPathException Thrown when an item does not have an associated URL.
 */
public static String[] getUrls(Sequence s) throws XPathException {
    final ArrayList<String> urls = new ArrayList<>();
    final SequenceIterator i = s.iterate();
    while (i.hasNext()) {
        final Item next = i.nextItem();
        final String url = getUrl(next);
        urls.add(url);
    }
    String[] returnUrls = new String[urls.size()];
    returnUrls = urls.toArray(returnUrls);
    return returnUrls;
}
Also used : Item(org.exist.xquery.value.Item) ValidationReportItem(org.exist.validation.ValidationReportItem) SequenceIterator(org.exist.xquery.value.SequenceIterator) ArrayList(java.util.ArrayList)

Example 5 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class Insert method seq2nodeList.

private NodeList seq2nodeList(Sequence contentSeq) throws XPathException {
    final NodeListImpl nl = new NodeListImpl();
    for (final SequenceIterator i = contentSeq.iterate(); i.hasNext(); ) {
        final Item item = i.nextItem();
        if (Type.subTypeOf(item.getType(), Type.NODE)) {
            final NodeValue val = (NodeValue) item;
            nl.add(val.getNode());
        }
    }
    return nl;
}
Also used : Item(org.exist.xquery.value.Item) NodeValue(org.exist.xquery.value.NodeValue) NodeListImpl(org.exist.dom.NodeListImpl) SequenceIterator(org.exist.xquery.value.SequenceIterator)

Aggregations

Item (org.exist.xquery.value.Item)88 Sequence (org.exist.xquery.value.Sequence)69 SequenceIterator (org.exist.xquery.value.SequenceIterator)36 XPathException (org.exist.xquery.XPathException)26 DBBroker (org.exist.storage.DBBroker)18 NodeValue (org.exist.xquery.value.NodeValue)17 XQuery (org.exist.xquery.XQuery)16 ValueSequence (org.exist.xquery.value.ValueSequence)16 BrokerPool (org.exist.storage.BrokerPool)14 NumericValue (org.exist.xquery.value.NumericValue)12 SAXException (org.xml.sax.SAXException)11 Properties (java.util.Properties)10 StringValue (org.exist.xquery.value.StringValue)10 Node (org.w3c.dom.Node)10 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)9 AtomicValue (org.exist.xquery.value.AtomicValue)9 Txn (org.exist.storage.txn.Txn)8 IOException (java.io.IOException)7 StringWriter (java.io.StringWriter)7 EXistException (org.exist.EXistException)7