Search in sources :

Example 21 with AtomicValue

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

the class FunMax method eval.

/* (non-Javadoc)
	 * @see org.exist.xquery.Expression#eval(org.exist.dom.persistent.DocumentSet, org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
	 */
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());
        }
    }
    Sequence result;
    final Sequence arg = getArgument(0).eval(contextSequence, contextItem);
    if (arg.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        boolean computableProcessing = false;
        // TODO : test if a range index is defined *iff* it is compatible with the collator
        final Collator collator = getCollator(contextSequence, contextItem, 2);
        final SequenceIterator iter = arg.unorderedIterator();
        AtomicValue max = null;
        while (iter.hasNext()) {
            final Item item = iter.nextItem();
            if (item instanceof QNameValue) {
                throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(item.getType()), arg);
            }
            AtomicValue value = item.atomize();
            // Duration values must either all be xs:yearMonthDuration values or must all be xs:dayTimeDuration values.
            if (Type.subTypeOf(value.getType(), Type.DURATION)) {
                value = ((DurationValue) value).wrap();
                if (value.getType() == Type.YEAR_MONTH_DURATION) {
                    if (max != null && max.getType() != Type.YEAR_MONTH_DURATION) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), value);
                    }
                } else if (value.getType() == Type.DAY_TIME_DURATION) {
                    if (max != null && max.getType() != Type.DAY_TIME_DURATION) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), value);
                    }
                } else {
                    throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(value.getType()), value);
                }
            // Any value of type xdt:untypedAtomic is cast to xs:double
            } else if (value.getType() == Type.UNTYPED_ATOMIC) {
                value = value.convertTo(Type.DOUBLE);
            }
            if (max == null) {
                max = value;
            } else {
                if (Type.getCommonSuperType(max.getType(), value.getType()) == Type.ATOMIC) {
                    throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), max);
                }
                // Any value of type xdt:untypedAtomic is cast to xs:double
                if (value.getType() == Type.UNTYPED_ATOMIC) {
                    value = value.convertTo(Type.DOUBLE);
                }
                // Numeric tests
                if (Type.subTypeOfUnion(value.getType(), Type.NUMBER)) {
                    // Don't mix comparisons
                    if (!Type.subTypeOfUnion(max.getType(), Type.NUMBER)) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), max);
                    }
                    if (((NumericValue) value).isNaN()) {
                        // Type NaN correctly
                        value = value.promote(max);
                        if (value.getType() == Type.FLOAT) {
                            max = FloatValue.NaN;
                        } else {
                            max = DoubleValue.NaN;
                        }
                        // although result will be NaN, we need to continue on order to type correctly
                        continue;
                    } else {
                        max = max.promote(value);
                    }
                }
                // Ugly test
                if (max instanceof ComputableValue && value instanceof ComputableValue) {
                    // Type value correctly
                    value = value.promote(max);
                    max = (ComputableValue) max.max(collator, value);
                    computableProcessing = true;
                } else {
                    if (computableProcessing) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), max);
                    }
                    if (Collations.compare(collator, value.getStringValue(), max.getStringValue()) > 0) {
                        max = value;
                    }
                }
            }
        }
        result = max;
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : Item(org.exist.xquery.value.Item) ComputableValue(org.exist.xquery.value.ComputableValue) SequenceIterator(org.exist.xquery.value.SequenceIterator) XPathException(org.exist.xquery.XPathException) QNameValue(org.exist.xquery.value.QNameValue) AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) NumericValue(org.exist.xquery.value.NumericValue) Collator(com.ibm.icu.text.Collator)

Example 22 with AtomicValue

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

the class ValueComparison method genericCompare.

protected Sequence genericCompare(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().message(this, Profiler.OPTIMIZATION_FLAGS, "OPTIMIZATION CHOICE", "genericCompare");
    }
    final Sequence ls = getLeft().eval(contextSequence, contextItem);
    final Sequence rs = getRight().eval(contextSequence, contextItem);
    if (ls.isEmpty() || rs.isEmpty()) {
        return Sequence.EMPTY_SEQUENCE;
    }
    if (ls.hasOne() && rs.hasOne()) {
        final AtomicValue lv = ls.itemAt(0).atomize();
        final AtomicValue rv = rs.itemAt(0).atomize();
        final Collator collator = getCollator(contextSequence);
        return BooleanValue.valueOf(compareAtomic(collator, lv, rv, StringTruncationOperator.NONE, relation));
    }
    throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: sequence with more than one item is not allowed here");
}
Also used : AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) Collator(com.ibm.icu.text.Collator)

Example 23 with AtomicValue

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

the class SwitchExpression method eval.

public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (getContext().getXQueryVersion() < 30) {
        throw new XPathException(this, ErrorCodes.EXXQDY0003, "switch expression is not available before XQuery 3.0", contextSequence);
    }
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    final Sequence opSeq = operand.eval(contextSequence);
    Sequence result = null;
    if (opSeq.isEmpty()) {
        result = defaultClause.returnClause.eval(contextSequence);
    } else {
        if (opSeq.hasMany()) {
            throw new XPathException(this, ErrorCodes.XPTY0004, "Cardinality error in switch operand ", opSeq);
        }
        final AtomicValue opVal = opSeq.itemAt(0).atomize();
        final Collator defaultCollator = context.getDefaultCollator();
        for (final Case next : cases) {
            for (final Expression caseOperand : next.operands) {
                final Sequence caseSeq = caseOperand.eval(contextSequence, contextItem);
                if (caseSeq.hasMany()) {
                    throw new XPathException(this, ErrorCodes.XPTY0004, "Cardinality error in switch case operand ", caseSeq);
                }
                final AtomicValue caseVal = caseSeq.isEmpty() ? AtomicValue.EMPTY_VALUE : caseSeq.itemAt(0).atomize();
                if (FunDeepEqual.deepEquals(caseVal, opVal, defaultCollator)) {
                    return next.returnClause.eval(contextSequence);
                }
            }
        }
    }
    if (result == null) {
        result = defaultClause.returnClause.eval(contextSequence);
    }
    return result;
}
Also used : AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) Collator(com.ibm.icu.text.Collator)

Example 24 with AtomicValue

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

the class QNameIndexLookup method eval.

public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (contextSequence == null || contextSequence.isEmpty()) {
        // if the context sequence is empty, we create a default context
        final RootNode rootNode = new RootNode(context);
        contextSequence = rootNode.eval(null, null);
    }
    final Sequence[] args = getArguments(null, null);
    final Item item = args[0].itemAt(0);
    final QNameValue qval;
    try {
        // attempt to convert the first argument to a QName
        qval = (QNameValue) item.convertTo(Type.QNAME);
    } catch (final XPathException e) {
        // wrong type: generate a diagnostic error
        throw new XPathException(this, Messages.formatMessage(Error.FUNC_PARAM_TYPE, new Object[] { "1", getSignature().toString(), null, Type.getTypeName(Type.QNAME), Type.getTypeName(item.getType()) }));
    }
    QName qname = qval.getQName();
    if (args.length == 3 && !(args[2].itemAt(0).toJavaObject(boolean.class))) {
        qname = new QName(qname.getLocalPart(), qname.getNamespaceURI(), qname.getPrefix(), ElementValue.ATTRIBUTE);
    }
    final AtomicValue comparisonCriterion = args[1].itemAt(0).atomize();
    final NativeValueIndex valueIndex = context.getBroker().getValueIndex();
    final Sequence result = valueIndex.find(context.getWatchDog(), Comparison.EQ, contextSequence.getDocumentSet(), null, NodeSet.ANCESTOR, qname, comparisonCriterion);
    return result;
}
Also used : RootNode(org.exist.xquery.RootNode) Item(org.exist.xquery.value.Item) XPathException(org.exist.xquery.XPathException) QName(org.exist.dom.QName) QNameValue(org.exist.xquery.value.QNameValue) AtomicValue(org.exist.xquery.value.AtomicValue) NativeValueIndex(org.exist.storage.NativeValueIndex) Sequence(org.exist.xquery.value.Sequence)

Example 25 with AtomicValue

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

the class NativeValueIndexTest method convertToAtomic.

@Test
public void convertToAtomic() throws XPathException {
    final String mockValue = "1234567890";
    final AtomicValue result = NativeValueIndex.convertToAtomic(type, mockValue);
    assertEquals(type, result.getType());
    assertEquals(mockValue, result.getStringValue());
}
Also used : AtomicValue(org.exist.xquery.value.AtomicValue) Test(org.junit.Test)

Aggregations

AtomicValue (org.exist.xquery.value.AtomicValue)26 Sequence (org.exist.xquery.value.Sequence)16 Collator (com.ibm.icu.text.Collator)9 Item (org.exist.xquery.value.Item)9 SequenceIterator (org.exist.xquery.value.SequenceIterator)9 XPathException (org.exist.xquery.XPathException)6 NumericValue (org.exist.xquery.value.NumericValue)6 StringValue (org.exist.xquery.value.StringValue)5 NodeProxy (org.exist.dom.persistent.NodeProxy)4 ComputableValue (org.exist.xquery.value.ComputableValue)4 IOException (java.io.IOException)3 QName (org.exist.dom.QName)3 QNameValue (org.exist.xquery.value.QNameValue)3 ValueSequence (org.exist.xquery.value.ValueSequence)3 Test (org.junit.Test)3 ReentrantLock (java.util.concurrent.locks.ReentrantLock)2 EXistException (org.exist.EXistException)2 Collection (org.exist.collections.Collection)2 ContextItem (org.exist.dom.persistent.ContextItem)2 NodeSet (org.exist.dom.persistent.NodeSet)2