Exemple #1
0
Expression::Ptr CountFN::compress(const StaticContext::Ptr &context)
{
    const Expression::Ptr me(FunctionCall::compress(context));
    if(me != this)
        return me;

    const Cardinality card(m_operands.first()->staticType()->cardinality());
    if(card.isExactlyOne())
        return wrapLiteral(CommonValues::IntegerOne, context, this);
    else if(card.isEmpty())
    {
        /* One might think that if the operand is (), that compress() would have
         * evaluated us and therefore this line never be reached, but "()" can
         * be combined with the DisableElimination flag. */
        return wrapLiteral(CommonValues::IntegerZero, context, this);
    }
    else if(card.isExact())
        return wrapLiteral(Integer::fromValue(card.minimum()), context, this);
    else
        return me;
}
Expression::Ptr ForClause::typeCheck(const StaticContext::Ptr &context,
                                     const SequenceType::Ptr &reqType)
{
    const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
    const Cardinality card(m_operand1->staticType()->cardinality());

    /* If our source is empty we will always evaluate to the empty sequence, so rewrite. */
    if(card.isEmpty())
        return EmptySequence::create(this, context);
    else
        return me;

    /* This breaks because  the variable references haven't rewritten themselves, so
     * they dangle. When this is fixed, evaluateSingleton can be removed. */
    /*
    else if(card->allowsMany())
        return me;
    else
        return m_operand2;
        */
}
Expression::Ptr CardinalityVerifier::verifyCardinality(const Expression::Ptr &operand,
                                                       const Cardinality &requiredCard,
                                                       const StaticContext::Ptr &context,
                                                       const ReportContext::ErrorCode code)
{
    const Cardinality opCard(operand->staticType()->cardinality());

    if(requiredCard.isMatch(opCard))
        return operand;
    else if(requiredCard.canMatch(opCard))
        return Expression::Ptr(new CardinalityVerifier(operand, requiredCard, code));
    else if(context->compatModeEnabled() &&
            !opCard.isEmpty())
    {
        return GenericPredicate::createFirstItem(operand);
    }
    else
    {
        /* Sequences within this cardinality can never match. */
        context->error(wrongCardinality(requiredCard, opCard), code, operand.data());
        return operand;
    }
}