Esempio n. 1
0
            internal static void CheckConstraints(CellTreeNode node, LeftCellWrapper wrapper,
                                                  ViewgenContext context, ErrorLog errorLog)
            {
                DomainConstraintVisitor visitor = new DomainConstraintVisitor(wrapper, context, errorLog);

                node.Accept <bool, bool>(visitor, true);
            }
        internal void Validate()
        {
            // turn rewritings into cell trees
            // plain: according to rewritings for case statements
            var plainMemberValueTrees = CreateMemberValueTrees(false);
            // complement: uses complement rewriting for the last WHEN ... THEN
            // This is how the final case statement will be generated in update views
            var complementMemberValueTrees = CreateMemberValueTrees(true);

            var plainWhereClauseVisitor      = new WhereClauseVisitor(_basicView, plainMemberValueTrees);
            var complementWhereClauseVisitor = new WhereClauseVisitor(_basicView, complementMemberValueTrees);

            // produce CellTree for each SQuery
            foreach (var wrapper in _viewgenContext.AllWrappersForExtent)
            {
                var cell = wrapper.OnlyInputCell;
                // construct cell tree for CQuery
                CellTreeNode cQueryTree = new LeafCellTreeNode(_viewgenContext, wrapper);
                // sQueryTree: unfolded update view inside S-side of the cell
                CellTreeNode sQueryTree;
                // construct cell tree for SQuery (will be used for domain constraint checking)
                var complementSQueryTreeForCondition = complementWhereClauseVisitor.GetCellTreeNode(cell.SQuery.WhereClause);
                Debug.Assert(complementSQueryTreeForCondition != null, "Rewriting for S-side query is unsatisfiable");
                if (complementSQueryTreeForCondition == null)
                {
                    continue; // situation should never happen
                }
                if (complementSQueryTreeForCondition != _basicView)
                {
                    // intersect with basic expression
                    sQueryTree = new OpCellTreeNode(_viewgenContext, CellTreeOpType.IJ, complementSQueryTreeForCondition, _basicView);
                }
                else
                {
                    sQueryTree = _basicView;
                }

                // Append in-set or in-end condition to both queries to produce more concise errors
                // Otherwise, the errors are of the form "if there exists an entity in extent, then violation". We don't care about empty extents
                var inExtentCondition = BoolExpression.CreateLiteral(wrapper.CreateRoleBoolean(), _viewgenContext.MemberMaps.QueryDomainMap);

                BoolExpression unsatisfiedConstraint;
                if (!CheckEquivalence(
                        cQueryTree.RightFragmentQuery, sQueryTree.RightFragmentQuery, inExtentCondition,
                        out unsatisfiedConstraint))
                {
                    var extentName = StringUtil.FormatInvariant("{0}", _viewgenContext.Extent);

                    // Simplify to produce more readable error messages
                    cQueryTree.RightFragmentQuery.Condition.ExpensiveSimplify();
                    sQueryTree.RightFragmentQuery.Condition.ExpensiveSimplify();

                    var message = Strings.ViewGen_CQ_PartitionConstraint(extentName);

                    ReportConstraintViolation(
                        message, unsatisfiedConstraint, ViewGenErrorCode.PartitionConstraintViolation,
                        cQueryTree.GetLeaves().Concat(sQueryTree.GetLeaves()));
                }

                var plainSQueryTreeForCondition = plainWhereClauseVisitor.GetCellTreeNode(cell.SQuery.WhereClause);
                Debug.Assert(plainSQueryTreeForCondition != null, "Rewriting for S-side query is unsatisfiable");
                if (plainSQueryTreeForCondition != null)
                {
                    // Query is non-empty. Check domain constraints on:
                    // (a) swapped members
                    DomainConstraintVisitor.CheckConstraints(plainSQueryTreeForCondition, wrapper, _viewgenContext, _errorLog);
                    //If you have already found errors, just continue on to the next wrapper instead of                    //collecting more errors for the same
                    if (_errorLog.Count > 0)
                    {
                        continue;
                    }
                    // (b) projected members
                    CheckConstraintsOnProjectedConditionMembers(plainMemberValueTrees, wrapper, sQueryTree, inExtentCondition);
                    if (_errorLog.Count > 0)
                    {
                        continue;
                    }
                }
                CheckConstraintsOnNonNullableMembers(wrapper);
            }

            if (_errorLog.Count > 0)
            {
                ExceptionHelpers.ThrowMappingException(_errorLog, _viewgenContext.Config);
            }
        }