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