/// <summary> /// Enumerates the terms of an expression tree that are specific to a table. /// </summary> /// <param name="node"></param> /// <param name="table"></param> /// <returns></returns> /// <remarks>The expression must be in CNF</remarks> private static IEnumerable<LogicalExpressions.Expression> EnumerateCnfTermsSpecificToTable(LogicalExpressions.Expression node, TableReference table) { foreach (var term in EnumerateCnfTerms(node)) { if (term is LogicalExpressions.OperatorOr) { // A term is only specific to a table if it contains predicates // only specific to the particular table var specifictotable = true; foreach (var exp in EnumerateCnfTermPredicates(term)) { if (!GetCnfLiteralPredicate(exp).IsSpecificToTable(table)) { specifictotable = false; break; } } if (specifictotable) { yield return term; } } else { if (GetCnfLiteralPredicate(term).IsSpecificToTable(table)) { yield return term; } } } }
/// <summary> /// Returns a search condition predicate associated with a CNF literal /// </summary> /// <param name="term"></param> /// <returns></returns> private static Predicate GetCnfLiteralPredicate(LogicalExpressions.Expression term) { if (term is LogicalExpressions.OperatorNot) { return ((LogicalExpressions.Predicate)((LogicalExpressions.OperatorNot)term).Operand).Value; } else if (term is LogicalExpressions.Predicate) { return ((LogicalExpressions.Predicate)term).Value; } else { throw new InvalidOperationException(); } }
/// <summary> /// Enumerates terms of an expression tree of a search condition. /// </summary> /// <param name="node"></param> /// <returns></returns> /// <remarks>The expression tree must be in CNF</remarks> private static IEnumerable<LogicalExpressions.Expression> EnumerateCnfTerms(LogicalExpressions.Expression node) { if (node == null) { throw new ArgumentNullException("node"); } if (node is LogicalExpressions.OperatorAnd) { // The CNF has multiple terms foreach (var exp in ((LogicalExpressions.OperatorAnd)node).EnumerateTerms()) { yield return exp; } } else if (node is LogicalExpressions.OperatorOr || node is LogicalExpressions.OperatorNot || node is LogicalExpressions.Predicate) { // The CNF has only one term yield return node; } else { throw new InvalidOperationException(); } }