private static bool HasNotNullCondition(CellQuery cellQuery, MemberPath member) { foreach (var condition in cellQuery.GetConjunctsFromWhereClause()) { if (condition.RestrictedMemberSlot.MemberPath.Equals(member)) { if (condition.Domain.Values.Contains(Constant.NotNull)) { return(true); } //Not Null may have been optimized into NOT(1, 2, NULL). SO look into negated cell constants foreach ( var negatedConst in condition.Domain.Values.Select(cellConstant => cellConstant as NegatedConstant).Where( negated => negated != null)) { if (negatedConst.Elements.Contains(Constant.Null)) { return(true); } } } } return(false); }
private static bool HasNotNullCondition(CellQuery cellQuery, MemberPath member) { foreach (MemberRestriction memberRestriction in cellQuery.GetConjunctsFromWhereClause()) { if (memberRestriction.RestrictedMemberSlot.MemberPath.Equals(member)) { if (memberRestriction.Domain.Values.Contains <Constant>(Constant.NotNull)) { return(true); } foreach (NegatedConstant negatedConstant in memberRestriction.Domain.Values.Select <Constant, NegatedConstant>((Func <Constant, NegatedConstant>)(cellConstant => cellConstant as NegatedConstant)).Where <NegatedConstant>((Func <NegatedConstant, bool>)(negated => negated != null))) { if (negatedConstant.Elements.Contains <Constant>(Constant.Null)) { return(true); } } } } return(false); }
/// <summary> /// Finds errors related to splitting Conditions /// 1. Condition value is repeated across multiple types /// 2. A Column/attribute is mapped but also used as a condition /// </summary> private void MatchConditionErrors() { List <LeftCellWrapper> leftCellWrappers = m_viewgenContext.AllWrappersForExtent; //Stores violating Discriminator (condition member) so that we dont repeat the same error Set <MemberPath> mappedConditionMembers = new Set <MemberPath>(); //Both of these data-structs help in finding duplicate conditions Set <CompositeCondition> setOfconditions = new Set <CompositeCondition>(new ConditionComparer()); Dictionary <CompositeCondition, LeftCellWrapper> firstLCWForCondition = new Dictionary <CompositeCondition, LeftCellWrapper>(new ConditionComparer()); foreach (var leftCellWrapper in leftCellWrappers) { CompositeCondition condMembersValues = new CompositeCondition(); CellQuery cellQuery = leftCellWrapper.OnlyInputCell.GetLeftQuery(m_viewgenContext.ViewTarget); foreach (MemberRestriction condition in cellQuery.GetConjunctsFromWhereClause()) { MemberPath memberPath = condition.RestrictedMemberSlot.MemberPath; if (!m_domainMap.IsConditionMember(memberPath)) { continue; } ScalarRestriction scalarCond = condition as ScalarRestriction; //Check for mapping of Scalar member condition, ignore type conditions if (scalarCond != null && !mappedConditionMembers.Contains(memberPath) && /* prevents duplicate errors */ !leftCellWrapper.OnlyInputCell.CQuery.WhereClause.Equals(leftCellWrapper.OnlyInputCell.SQuery.WhereClause) && /* projection allowed when both conditions are equal */ !IsMemberPartOfNotNullCondition(leftCellWrappers, memberPath, m_viewgenContext.ViewTarget)) { //This member should not be mapped CheckThatConditionMemberIsNotMapped(memberPath, leftCellWrappers, mappedConditionMembers); } //If a not-null condition is specified on a nullable column, //check that the property it is mapped to in the fragment is non-nullable, //unless there is a not null condition on the property that is being mapped it self. //Otherwise return an error. if (m_viewgenContext.ViewTarget == ViewTarget.UpdateView) { if (scalarCond != null && memberPath.IsNullable && IsMemberPartOfNotNullCondition(new LeftCellWrapper[] { leftCellWrapper }, memberPath, m_viewgenContext.ViewTarget)) { MemberPath rightMemberPath = GetRightMemberPath(memberPath, leftCellWrapper); if (rightMemberPath != null && rightMemberPath.IsNullable && !IsMemberPartOfNotNullCondition(new LeftCellWrapper[] { leftCellWrapper }, rightMemberPath, m_viewgenContext.ViewTarget)) { m_errorLog.AddEntry(new ErrorLog.Record(true, ViewGenErrorCode.ErrorPatternConditionError, Strings.Viewgen_ErrorPattern_NotNullConditionMappedToNullableMember( memberPath, rightMemberPath ), leftCellWrapper.OnlyInputCell, "")); } } } //CheckForDuplicateConditionValue //discover a composite condition of the form {path1=x, path2=y, ...} foreach (var element in condition.Domain.Values) { Set <Constant> values; //if not in the dict, add it if (!condMembersValues.TryGetValue(memberPath, out values)) { values = new Set <Constant>(Constant.EqualityComparer); condMembersValues.Add(memberPath, values); } values.Add(element); } } //foreach condition if (condMembersValues.Count > 0) //it is possible that there are no condition members { //Check if the composite condition has been encountered before if (setOfconditions.Contains(condMembersValues)) { //Extents may be Equal on right side (e.g: by some form of Refconstraint) if (!RightSideEqual(firstLCWForCondition[condMembersValues], leftCellWrapper)) { //error duplicate conditions m_errorLog.AddEntry(new ErrorLog.Record(true, ViewGenErrorCode.ErrorPatternConditionError, Strings.Viewgen_ErrorPattern_DuplicateConditionValue( BuildCommaSeparatedErrorString <MemberPath>(condMembersValues.Keys) ), ToIEnum(firstLCWForCondition[condMembersValues].OnlyInputCell, leftCellWrapper.OnlyInputCell), "")); } } else { setOfconditions.Add(condMembersValues); //Remember which cell the condition came from.. used for error reporting firstLCWForCondition.Add(condMembersValues, leftCellWrapper); } } } //foreach fragment related to the Extent we are working on }