// Checks equivalence of two C-side queries // inExtentConstraint holds a role variable that effectively denotes that some extent is non-empty private bool CheckEquivalence( FragmentQuery cQuery, FragmentQuery sQuery, BoolExpression inExtentCondition, out BoolExpression unsatisfiedConstraint) { var cMinusSx = _viewgenContext.RightFragmentQP.Difference(cQuery, sQuery); var sMinusCx = _viewgenContext.RightFragmentQP.Difference(sQuery, cQuery); // add in-extent condition var cMinusS = FragmentQuery.Create(BoolExpression.CreateAnd(cMinusSx.Condition, inExtentCondition)); var sMinusC = FragmentQuery.Create(BoolExpression.CreateAnd(sMinusCx.Condition, inExtentCondition)); unsatisfiedConstraint = null; var forwardInclusion = true; var backwardInclusion = true; if (_viewgenContext.RightFragmentQP.IsSatisfiable(cMinusS)) { unsatisfiedConstraint = cMinusS.Condition; forwardInclusion = false; } if (_viewgenContext.RightFragmentQP.IsSatisfiable(sMinusC)) { unsatisfiedConstraint = sMinusC.Condition; backwardInclusion = false; } if (forwardInclusion && backwardInclusion) { return(true); } else { unsatisfiedConstraint.ExpensiveSimplify(); return(false); } }
// effects: Given the cells for the extent (extentCells) along with // the signatures (multiconstants + needed attributes) for this extent, generates // the left cell wrappers for it extent (viewTarget indicates whether // the view is for querying or update purposes // Modifies m_cellWrappers to contain this list private bool CreateLeftCellWrappers(IList <Cell> extentCells, ViewTarget viewTarget) { var alignedCells = AlignFields(extentCells, m_memberMaps.ProjectedSlotMap, viewTarget); Debug.Assert(alignedCells.Count == extentCells.Count, "Cell counts disagree"); // Go through all the cells and create cell wrappers that can be used for generating the view m_cellWrappers = new List <LeftCellWrapper>(); for (var i = 0; i < alignedCells.Count; i++) { var alignedCell = alignedCells[i]; var left = alignedCell.GetLeftQuery(viewTarget); var right = alignedCell.GetRightQuery(viewTarget); // Obtain the non-null projected slots into attributes var attributes = left.GetNonNullSlots(); var fromVariable = BoolExpression.CreateLiteral( new CellIdBoolean(m_identifiers, extentCells[i].CellNumber), m_memberMaps.LeftDomainMap); var leftFragmentQuery = FragmentQuery.Create(fromVariable, left); if (viewTarget == ViewTarget.UpdateView) { leftFragmentQuery = m_leftFragmentQP.CreateDerivedViewBySelectingConstantAttributes(leftFragmentQuery) ?? leftFragmentQuery; } var leftWrapper = new LeftCellWrapper( m_viewTarget, attributes, leftFragmentQuery, left, right, m_memberMaps, extentCells[i]); m_cellWrappers.Add(leftWrapper); } return(true); }
private bool CheckEquivalence( FragmentQuery cQuery, FragmentQuery sQuery, BoolExpression inExtentCondition, out BoolExpression unsatisfiedConstraint) { FragmentQuery fragmentQuery1 = this._viewgenContext.RightFragmentQP.Difference(cQuery, sQuery); FragmentQuery fragmentQuery2 = this._viewgenContext.RightFragmentQP.Difference(sQuery, cQuery); FragmentQuery query1 = FragmentQuery.Create(BoolExpression.CreateAnd(fragmentQuery1.Condition, inExtentCondition)); FragmentQuery query2 = FragmentQuery.Create(BoolExpression.CreateAnd(fragmentQuery2.Condition, inExtentCondition)); unsatisfiedConstraint = (BoolExpression)null; bool flag1 = true; bool flag2 = true; if (this._viewgenContext.RightFragmentQP.IsSatisfiable(query1)) { unsatisfiedConstraint = query1.Condition; flag1 = false; } if (this._viewgenContext.RightFragmentQP.IsSatisfiable(query2)) { unsatisfiedConstraint = query2.Condition; flag2 = false; } if (flag1 && flag2) { return(true); } unsatisfiedConstraint.ExpensiveSimplify(); return(false); }
// effects: Encapsulate the cell wrapper in the node internal LeafCellTreeNode(ViewgenContext context, LeftCellWrapper cellWrapper) : base(context) { m_cellWrapper = cellWrapper; cellWrapper.AssertHasUniqueCell(); m_rightFragmentQuery = FragmentQuery.Create( cellWrapper.OriginalCellNumberString, cellWrapper.CreateRoleBoolean(), cellWrapper.RightCellQuery); }
private static bool CheckConstraintWhenOnlyParentMapped( AssociationSet assocSet, AssociationEndMember endMember, QueryRewriter childRewriter, QueryRewriter parentRewriter) { ViewgenContext viewgenContext1 = childRewriter.ViewgenContext; ViewgenContext viewgenContext2 = parentRewriter.ViewgenContext; CellTreeNode basicView = parentRewriter.BasicView; RoleBoolean roleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]); BoolExpression whereClause = basicView.RightFragmentQuery.Condition.Create((BoolLiteral)roleBoolean); FragmentQuery q1 = FragmentQuery.Create((IEnumerable <MemberPath>)basicView.RightFragmentQuery.Attributes, whereClause); return(FragmentQueryProcessor.Merge(viewgenContext1.RightFragmentQP, viewgenContext2.RightFragmentQP).IsContainedIn(q1, basicView.RightFragmentQuery)); }
private void CheckConstraintsOnProjectedConditionMembers( Dictionary <RewritingValidator.MemberValueBinding, CellTreeNode> memberValueTrees, LeftCellWrapper wrapper, CellTreeNode sQueryTree, BoolExpression inExtentCondition) { foreach (MemberPath conditionMember in this._domainMap.ConditionMembers(this._viewgenContext.Extent)) { int slotNum = this._viewgenContext.MemberMaps.ProjectedSlotMap.IndexOf(conditionMember); MemberProjectedSlot memberProjectedSlot = wrapper.RightCellQuery.ProjectedSlotAt(slotNum) as MemberProjectedSlot; if (memberProjectedSlot != null) { foreach (Constant constant in this._domainMap.GetDomain(conditionMember)) { CellTreeNode cellTreeNode1; if (memberValueTrees.TryGetValue(new RewritingValidator.MemberValueBinding(conditionMember, constant), out cellTreeNode1)) { FragmentQuery cQuery = FragmentQuery.Create(RewritingValidator.PropagateCellConstantsToWhereClause(wrapper, wrapper.RightCellQuery.WhereClause, constant, conditionMember, this._viewgenContext.MemberMaps)); CellTreeNode cellTreeNode2; if (sQueryTree != this._basicView) { cellTreeNode2 = (CellTreeNode) new OpCellTreeNode(this._viewgenContext, CellTreeOpType.IJ, new CellTreeNode[2] { cellTreeNode1, sQueryTree }); } else { cellTreeNode2 = cellTreeNode1; } CellTreeNode cellTreeNode3 = cellTreeNode2; BoolExpression unsatisfiedConstraint; if (!this.CheckEquivalence(cQuery, cellTreeNode3.RightFragmentQuery, inExtentCondition, out unsatisfiedConstraint)) { this.ReportConstraintViolation(Strings.ViewGen_CQ_DomainConstraint((object)memberProjectedSlot.ToUserString()), unsatisfiedConstraint, ViewGenErrorCode.DomainConstraintViolation, cellTreeNode3.GetLeaves().Concat <LeftCellWrapper>((IEnumerable <LeftCellWrapper>) new LeftCellWrapper[1] { wrapper })); } } } } } }
private void CheckConstraintsOnProjectedConditionMembers( Dictionary <MemberValueBinding, CellTreeNode> memberValueTrees, LeftCellWrapper wrapper, CellTreeNode sQueryTree, BoolExpression inExtentCondition) { // for S-side condition members that are projected, // add condition <member=value> on both sides of the mapping constraint, and check key equivalence // applies to columns that are (1) projected and (2) conditional foreach (var column in _domainMap.ConditionMembers(_viewgenContext.Extent)) { // Get the slot on the C side and see if it is projected var index = _viewgenContext.MemberMaps.ProjectedSlotMap.IndexOf(column); var slot = wrapper.RightCellQuery.ProjectedSlotAt(index) as MemberProjectedSlot; if (slot != null) { foreach (var domainValue in _domainMap.GetDomain(column)) { CellTreeNode sQueryTreeForDomainValue; if (memberValueTrees.TryGetValue(new MemberValueBinding(column, domainValue), out sQueryTreeForDomainValue)) { var cWhereClause = PropagateCellConstantsToWhereClause( wrapper, wrapper.RightCellQuery.WhereClause, domainValue, column, _viewgenContext.MemberMaps); var cCombinedQuery = FragmentQuery.Create(cWhereClause); var sCombinedTree = (sQueryTree == _basicView) ? sQueryTreeForDomainValue : new OpCellTreeNode( _viewgenContext, CellTreeOpType.IJ, sQueryTreeForDomainValue, sQueryTree); BoolExpression unsatisfiedConstraint; if (!CheckEquivalence( cCombinedQuery, sCombinedTree.RightFragmentQuery, inExtentCondition, out unsatisfiedConstraint)) { var memberLossMessage = Strings.ViewGen_CQ_DomainConstraint(slot.ToUserString()); ReportConstraintViolation( memberLossMessage, unsatisfiedConstraint, ViewGenErrorCode.DomainConstraintViolation, sCombinedTree.GetLeaves().Concat(new[] { wrapper })); } } } } } }
private static FragmentQuery AddNullConditionOnCSideFragment( LeftCellWrapper wrapper, MemberPath member, MemberMaps memberMaps) { MemberProjectedSlot mappedSlotForSmember = wrapper.GetCSideMappedSlotForSMember(member); if (mappedSlotForSmember == null || !mappedSlotForSmember.MemberPath.IsNullable) { return((FragmentQuery)null); } BoolExpression whereClause = wrapper.RightCellQuery.WhereClause; IEnumerable <Constant> domain = memberMaps.QueryDomainMap.GetDomain(mappedSlotForSmember.MemberPath); MemberRestriction memberRestriction = (MemberRestriction) new ScalarRestriction(mappedSlotForSmember.MemberPath, (IEnumerable <Constant>) new Set <Constant>(Constant.EqualityComparer) { Constant.Null }, domain); return(FragmentQuery.Create(BoolExpression.CreateAnd(whereClause, BoolExpression.CreateLiteral((BoolLiteral)memberRestriction, memberMaps.QueryDomainMap)))); }
private bool CreateLeftCellWrappers(IList <Cell> extentCells, ViewTarget viewTarget) { List <Cell> cellList = ViewgenContext.AlignFields((IEnumerable <Cell>)extentCells, this.m_memberMaps.ProjectedSlotMap, viewTarget); this.m_cellWrappers = new List <LeftCellWrapper>(); for (int index = 0; index < cellList.Count; ++index) { Cell cell = cellList[index]; CellQuery leftQuery = cell.GetLeftQuery(viewTarget); CellQuery rightQuery = cell.GetRightQuery(viewTarget); Set <MemberPath> nonNullSlots = leftQuery.GetNonNullSlots(); FragmentQuery fragmentQuery = FragmentQuery.Create(BoolExpression.CreateLiteral((BoolLiteral) new CellIdBoolean(this.m_identifiers, extentCells[index].CellNumber), this.m_memberMaps.LeftDomainMap), leftQuery); if (viewTarget == ViewTarget.UpdateView) { fragmentQuery = this.m_leftFragmentQP.CreateDerivedViewBySelectingConstantAttributes(fragmentQuery) ?? fragmentQuery; } this.m_cellWrappers.Add(new LeftCellWrapper(this.m_viewTarget, nonNullSlots, fragmentQuery, leftQuery, rightQuery, this.m_memberMaps, extentCells[index])); } return(true); }
// requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false // and primaryKeys of ChildTable are not mapped in cell. cell // corresponds to an association set. parentSet is the set // corresponding to the end that we are looking at // effects: Checks if the constraint is correctly maintained in // C-space via an association set (being a subset of the // corresponding entitySet) private static bool CheckConstraintWhenOnlyParentMapped( AssociationSet assocSet, AssociationEndMember endMember, QueryRewriter childRewriter, QueryRewriter parentRewriter) { var childContext = childRewriter.ViewgenContext; var parentContext = parentRewriter.ViewgenContext; var pNode = parentRewriter.BasicView; Debug.Assert(pNode != null); var endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]); // use query in pNode as a factory to create a bool expression for the endRoleBoolean var endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean); var cNodeQuery = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition); var qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP); var cImpliesP = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery); return(cImpliesP); }
// requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false // and primaryKeys of ChildTable are not mapped in cell. cell // corresponds to an association set. parentSet is the set // corresponding to the end that we are looking at // effects: Checks if the constraint is correctly maintained in // C-space via an association set (being a subset of the // corresponding entitySet) private bool CheckConstraintWhenOnlyParentMapped(Cell cell, EntitySet parentSet, AssociationSet assocSet, AssociationEndMember endMember, QueryRewriter childRewriter, QueryRewriter parentRewriter, ConfigViewGenerator config) { ViewgenContext childContext = childRewriter.ViewgenContext; ViewgenContext parentContext = parentRewriter.ViewgenContext; CellTreeNode pNode = parentRewriter.BasicView; Debug.Assert(pNode != null); RoleBoolean endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]); // use query in pNode as a factory to create a bool expression for the endRoleBoolean BoolExpression endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean); FragmentQuery cNodeQuery = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition); FragmentQueryProcessor qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP); bool cImpliesP = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery); return(cImpliesP); }
/// <summary> /// Given a LeftCellWrapper for the S-side fragment and a non-nullable colum m, return a CQuery with nullability condition /// appended to Cquery of c-side member that column m is mapped to /// </summary> private static FragmentQuery AddNullConditionOnCSideFragment(LeftCellWrapper wrapper, MemberPath member, MemberMaps memberMaps) { MemberProjectedSlot projectedSlot = wrapper.GetCSideMappedSlotForSMember(member); if (projectedSlot == null || !projectedSlot.MemberPath.IsNullable) //don't bother checking further fore non nullable C-side member { return(null); } BoolExpression expression = wrapper.RightCellQuery.WhereClause; IEnumerable <Constant> possibleValues = memberMaps.QueryDomainMap.GetDomain(projectedSlot.MemberPath); Set <Constant> allowedValues = new Set <Constant>(Constant.EqualityComparer); allowedValues.Add(Constant.Null); //Create a condition as conjunction of originalCondition and slot IS NULL MemberRestriction restriction = new ScalarRestriction(projectedSlot.MemberPath, allowedValues, possibleValues); BoolExpression resultingExpr = BoolExpression.CreateAnd(expression, BoolExpression.CreateLiteral(restriction, memberMaps.QueryDomainMap)); return(FragmentQuery.Create(resultingExpr)); }
private FragmentQuery CreateRightFragmentQuery(LeftCellWrapper wrapper) { return(FragmentQuery.Create( wrapper.OnlyInputCell.CellLabel.ToString(), wrapper.CreateRoleBoolean(), wrapper.OnlyInputCell.GetRightQuery(m_viewgenContext.ViewTarget))); }