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);
}
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;
}
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;
}
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;
}
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;
}
Aggregations