Ejemplo n.º 1
0
        // effects: Creates a map with all the condition member constants
        // from extentCells. viewtarget determines whether the view is an
        // update or query view
        internal MemberDomainMap(ViewTarget viewTarget, bool isValidationEnabled, IEnumerable <Cell> extentCells, EdmItemCollection edmItemCollection, ConfigViewGenerator config, Dictionary <EntityType, Set <EntityType> > inheritanceGraph)
        {
            m_conditionDomainMap = new Dictionary <MemberPath, CellConstantSet>(MemberPath.EqualityComparer);
            m_edmItemCollection  = edmItemCollection;

            Dictionary <MemberPath, CellConstantSet> domainMap = null;

            if (viewTarget == ViewTarget.UpdateView)
            {
                domainMap = Domain.ComputeConstantDomainSetsForSlotsInUpdateViews(extentCells, m_edmItemCollection);
            }
            else
            {
                domainMap = Domain.ComputeConstantDomainSetsForSlotsInQueryViews(extentCells, m_edmItemCollection, isValidationEnabled);
            }

            foreach (Cell cell in extentCells)
            {
                CellQuery cellQuery = cell.GetLeftQuery(viewTarget);
                // Get the atoms from cellQuery and only keep the ones that
                // are condition members
                foreach (MemberRestriction condition in cellQuery.GetConjunctsFromWhereClause())
                {
                    // Note: TypeConditions are created using OneOfTypeConst and
                    // scalars are created using OneOfScalarConst
                    MemberPath memberPath = condition.RestrictedMemberSlot.MemberPath;

                    Debug.Assert(condition is ScalarRestriction || condition is TypeRestriction,
                                 "Unexpected restriction");

                    // Take the narrowed domain from domainMap, if any
                    CellConstantSet domainValues;
                    if (!domainMap.TryGetValue(memberPath, out domainValues))
                    {
                        domainValues = Domain.DeriveDomainFromMemberPath(memberPath, edmItemCollection, isValidationEnabled);
                    }

                    //Don't count conditions that are satisfied through IsNull=false
                    if (!domainValues.Contains(Constant.Null))
                    {
                        //multiple values of condition represent disjunction in conditions (not currently supported)
                        // if there is any condition constant that is NotNull
                        if (condition.Domain.Values.All(conditionConstant => (conditionConstant.Equals(Constant.NotNull))))
                        {
                            continue;
                        }
                        //else there is atleast one condition value that is allowed, continue view generation
                    }

                    //------------------------------------------
                    //|  Nullable  |   IsNull  |   Test case   |
                    //|     T      |     T     |       T       |
                    //|     T      |     F     |       T       |
                    //|     F      |     T     |       F       |
                    //|     F      |     F     |       T       |
                    //------------------------------------------
                    //IsNull condition on a member that is non nullable is an invalid condition
                    if (domainValues.Count <= 0 || (!domainValues.Contains(Constant.Null) && condition.Domain.Values.Contains(Constant.Null)))
                    {
                        string          message = System.Data.Entity.Strings.ViewGen_InvalidCondition(memberPath.PathToString(false));
                        ErrorLog.Record record  = new ErrorLog.Record(true, ViewGenErrorCode.InvalidCondition, message, cell, String.Empty);
                        ExceptionHelpers.ThrowMappingException(record, config);
                    }
                    if (memberPath.IsAlwaysDefined(inheritanceGraph) == false)
                    {
                        domainValues.Add(Constant.Undefined);
                    }

                    AddToDomainMap(memberPath, domainValues);
                }
            }

            // Fill up the domains for the remaining slots as well
            m_nonConditionDomainMap = new Dictionary <MemberPath, CellConstantSet>(MemberPath.EqualityComparer);
            foreach (Cell cell in extentCells)
            {
                CellQuery cellQuery = cell.GetLeftQuery(viewTarget);
                // Get the atoms from cellQuery and only keep the ones that
                // are condition members
                foreach (MemberProjectedSlot slot in cellQuery.GetAllQuerySlots())
                {
                    MemberPath member = slot.MemberPath;
                    if (m_conditionDomainMap.ContainsKey(member) == false && m_nonConditionDomainMap.ContainsKey(member) == false)
                    {
                        CellConstantSet memberSet = Domain.DeriveDomainFromMemberPath(member, m_edmItemCollection, true /* Regardless of validation, leave the domain unbounded because this is not a condition member */);
                        if (member.IsAlwaysDefined(inheritanceGraph) == false)
                        { // nonConditionMember may belong to subclass
                            memberSet.Add(Constant.Undefined);
                        }
                        memberSet = Domain.ExpandNegationsInDomain(memberSet, memberSet);
                        m_nonConditionDomainMap.Add(member, new CellConstantSetInfo(memberSet, slot));
                    }
                }
            }
        }
Ejemplo n.º 2
0
        internal DbExpression AsCqt(DbExpression row, IEnumerable <Constant> constants, MemberPath outputMember, bool skipIsNotNull)
        {
            DbExpression cqt = null;

            AsCql(
                // trueLiteral action
                () => cqt = DbExpressionBuilder.True,
                // varIsNotNull action
                () => cqt = outputMember.AsCqt(row).IsNull().Not(),
                // varNotEqualsTo action
                (constant) =>
            {
                DbExpression notEqualsExpr = outputMember.AsCqt(row).NotEqual(constant.AsCqt(row, outputMember));
                if (cqt != null)
                {
                    cqt = cqt.And(notEqualsExpr);
                }
                else
                {
                    cqt = notEqualsExpr;
                }
            },
                constants, outputMember, skipIsNotNull);

            return(cqt);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Generates eSQL for the constant expression.
 /// </summary>
 /// <param name="outputMember">The member to which this constant is directed</param>
 internal abstract StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias);
Ejemplo n.º 4
0
 /// <summary>
 /// Creates a scalar member restriction with the meaning "<paramref name="member"/> in <paramref name="values"/>".
 /// </summary>
 internal ScalarRestriction(MemberPath member, IEnumerable <Constant> values, IEnumerable <Constant> possibleValues)
     : base(new MemberProjectedSlot(member), values, possibleValues)
 {
 }
Ejemplo n.º 5
0
 // effects: Creates a cell query with the given projection (slots),
 // from part (joinTreeRoot) and the predicate (whereClause)
 // Used for cell creation
 internal CellQuery(List <ProjectedSlot> slots, BoolExpression whereClause, MemberPath rootMember, SelectDistinct eliminateDuplicates)
     : this(slots.ToArray(), whereClause, new List <BoolExpression>(), eliminateDuplicates, rootMember)
 {
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Not supported in this class.
 /// </summary>
 internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
 {
     Debug.Fail("Should not be called.");
     return(null); // To keep the compiler happy
 }
Ejemplo n.º 7
0
        private static DbExpression CaseSlotValueAsCqt(DbExpression row, ProjectedSlot slot, MemberPath outputMember, IEnumerable <WithRelationship> withRelationships)
        {
            // We should never have THEN as a BooleanProjectedSlot.
            Debug.Assert(slot is MemberProjectedSlot || slot is QualifiedSlot || slot is ConstantProjectedSlot,
                         "Case statement THEN can only have constants or members.");
            DbExpression cqt = slot.AsCqt(row, outputMember);

            cqt = WithRelationshipsClauseAsCqt(row, cqt, withRelationships, slot);
            return(cqt);
        }
Ejemplo n.º 8
0
        private StringBuilder ToStringHelper(StringBuilder builder, string blockAlias, IEnumerable <Constant> constants, MemberPath outputMember, bool skipIsNotNull, bool userString)
        {
            bool anyAdded = false;

            AsCql(
                // trueLiteral action
                () => builder.Append("true"),
                // varIsNotNull action
                () =>
            {
                if (userString)
                {
                    outputMember.ToCompactString(builder, blockAlias);
                    builder.Append(" is not NULL");
                }
                else
                {
                    outputMember.AsEsql(builder, blockAlias);
                    builder.Append(" IS NOT NULL");
                }
                anyAdded = true;
            },
                // varNotEqualsTo action
                (constant) =>
            {
                if (anyAdded)
                {
                    builder.Append(" AND ");
                }
                anyAdded = true;

                if (userString)
                {
                    outputMember.ToCompactString(builder, blockAlias);
                    builder.Append(" <>");
                    constant.ToCompactString(builder);
                }
                else
                {
                    outputMember.AsEsql(builder, blockAlias);
                    builder.Append(" <>");
                    constant.AsEsql(builder, outputMember, blockAlias);
                }
            },
                constants, outputMember, skipIsNotNull);
            return(builder);
        }
Ejemplo n.º 9
0
 internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
 {
     return(m_caseStatement.AsCqt(row, m_withRelationships));
 }
Ejemplo n.º 10
0
 private static StringBuilder CaseSlotValueAsEsql(StringBuilder builder, ProjectedSlot slot, MemberPath outputMember, string blockAlias, IEnumerable <WithRelationship> withRelationships, int indentLevel)
 {
     // We should never have THEN as a BooleanProjectedSlot.
     Debug.Assert(slot is MemberProjectedSlot || slot is QualifiedSlot || slot is ConstantProjectedSlot,
                  "Case statement THEN can only have constants or members.");
     slot.AsEsql(builder, outputMember, blockAlias, 1);
     WithRelationshipsClauseAsEsql(builder, withRelationships, blockAlias, indentLevel, slot);
     return(builder);
 }
Ejemplo n.º 11
0
 internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias, int indentLevel)
 {
     m_caseStatement.AsEsql(builder, m_withRelationships, blockAlias, indentLevel);
     return(builder);
 }
        // effects: Generates a SlotInfo object for a slot of a join node. It
        // uses the type of the join operation (opType), whether the slot is
        // required by the parent or not (isRequiredSlot), the children of
        // this node (children) and the number of the slotNum
        private SlotInfo GetJoinSlotInfo(CellTreeOpType opType, bool isRequiredSlot,
                                         List <CqlBlock> children, int slotNum, CqlIdentifiers identifiers)
        {
            if (false == isRequiredSlot)
            {
                // The slot will not be used. So we can set the projected slot to be null
                SlotInfo unrequiredSlotInfo = new SlotInfo(false, false, null, GetMemberPath(slotNum));
                return(unrequiredSlotInfo);
            }

            // For a required slot, determine the child who is contributing to this value
            int           childDefiningSlot = -1;
            CaseStatement caseForOuterJoins = null;

            for (int childNum = 0; childNum < children.Count; childNum++)
            {
                CqlBlock child = children[childNum];
                if (false == child.IsProjected(slotNum))
                {
                    continue;
                }
                // For keys, we can pick any child block. So the first
                // one that we find is fine as well
                if (IsKeySlot(slotNum))
                {
                    childDefiningSlot = childNum;
                    break;
                }
                else if (opType == CellTreeOpType.IJ)
                {
                    // For Inner Joins, most of the time, the entries will be
                    // the same in all the children. However, in some cases,
                    // we will end up with NULL in one child and an actual
                    // value in another -- we should pick up the actual value in that case
                    childDefiningSlot = GetInnerJoinChildForSlot(children, slotNum);
                    break;
                }
                else
                {
                    // For LOJs, we generate a case statement if more than
                    // one child generates the value - until then we do not
                    // create the caseForOuterJoins object
                    if (childDefiningSlot != -1)
                    {
                        // We really need a case statement now
                        // We have the value being generated by another child
                        // We need to fetch the variable from the appropriate child
                        Debug.Assert(false == IsBoolSlot(slotNum), "Boolean slots cannot come from two children");
                        if (caseForOuterJoins == null)
                        {
                            MemberPath outputMember = GetMemberPath(slotNum);
                            caseForOuterJoins = new CaseStatement(outputMember);
                            // Add the child that we had not added in the first shot
                            AddCaseForOuterJoins(caseForOuterJoins, children[childDefiningSlot], slotNum, identifiers);
                        }
                        AddCaseForOuterJoins(caseForOuterJoins, child, slotNum, identifiers);
                    }
                    childDefiningSlot = childNum;
                }
            }

            MemberPath    memberPath = GetMemberPath(slotNum);
            ProjectedSlot slot       = null;

            // Generate the slot value -- case statement slot, or a qualified slot or null or false.
            // If case statement slot has nothing, treat it as null/empty.
            if (caseForOuterJoins != null && (caseForOuterJoins.Clauses.Count > 0 || caseForOuterJoins.ElseValue != null))
            {
                caseForOuterJoins.Simplify();
                slot = new CaseStatementProjectedSlot(caseForOuterJoins, null);
            }
            else if (childDefiningSlot >= 0)
            {
                slot = children[childDefiningSlot].QualifySlotWithBlockAlias(slotNum);
            }
            else
            {
                // need to produce output slot, but don't have a value
                // output NULL for fields or False for bools
                if (IsBoolSlot(slotNum))
                {
                    slot = new BooleanProjectedSlot(BoolExpression.False, identifiers, SlotToBoolIndex(slotNum));
                }
                else
                {
                    slot = new ConstantProjectedSlot(Domain.GetDefaultValueForMemberPath(memberPath, GetLeaves(), ViewgenContext.Config), memberPath);
                }
            }

            // We need to ensure that _from variables are never null since
            // view generation uses 2-valued boolean logic.
            // They can become null in outer joins. We compensate for it by
            // adding AND NOT NULL condition on boolean slots coming from outer joins.
            bool enforceNotNull = IsBoolSlot(slotNum) &&
                                  ((opType == CellTreeOpType.LOJ && childDefiningSlot > 0) ||
                                   opType == CellTreeOpType.FOJ);
            // We set isProjected to be true since we have come up with some value for it
            SlotInfo slotInfo = new SlotInfo(true, true, slot, memberPath, enforceNotNull);

            return(slotInfo);
        }
        // requires: node corresponds to a Union node
        // effects: Given a union node and the slots required by the parent,
        // generates a CqlBlock for the subtree rooted at node
        private CqlBlock UnionToCqlBlock(bool[] requiredSlots, CqlIdentifiers identifiers, ref int blockAliasNum, ref List <WithRelationship> withRelationships)
        {
            Debug.Assert(OpType == CellTreeOpType.Union);

            List <CqlBlock> children = new List <CqlBlock>();
            List <Tuple <CqlBlock, SlotInfo> > additionalChildSlots = new List <Tuple <CqlBlock, SlotInfo> >();

            int totalSlots = requiredSlots.Length;

            foreach (CellTreeNode child in Children)
            {
                // Unlike Join, we pass the requiredSlots from the parent as the requirement.
                bool[] childProjectedSlots = child.GetProjectedSlots();
                AndWith(childProjectedSlots, requiredSlots);
                CqlBlock childBlock = child.ToCqlBlock(childProjectedSlots, identifiers, ref blockAliasNum, ref withRelationships);
                for (int qualifiedSlotNumber = childProjectedSlots.Length; qualifiedSlotNumber < childBlock.Slots.Count; qualifiedSlotNumber++)
                {
                    additionalChildSlots.Add(Tuple.Create(childBlock, childBlock.Slots[qualifiedSlotNumber]));
                }

                // if required, but not projected, add NULL
                SlotInfo[] paddedSlotInfo = new SlotInfo[childBlock.Slots.Count];
                for (int slotNum = 0; slotNum < totalSlots; slotNum++)
                {
                    if (requiredSlots[slotNum] && !childProjectedSlots[slotNum])
                    {
                        if (IsBoolSlot(slotNum))
                        {
                            paddedSlotInfo[slotNum] = new SlotInfo(true /* is required */, true /* is projected */,
                                                                   new BooleanProjectedSlot(BoolExpression.False, identifiers, SlotToBoolIndex(slotNum)), null /* member path*/);
                        }
                        else
                        {
                            // NULL as projected slot
                            MemberPath memberPath = childBlock.MemberPath(slotNum);
                            paddedSlotInfo[slotNum] = new SlotInfo(true /* is required */, true /* is projected */,
                                                                   new ConstantProjectedSlot(Constant.Null, memberPath), memberPath);
                        }
                    }
                    else
                    {
                        paddedSlotInfo[slotNum] = childBlock.Slots[slotNum];
                    }
                }
                childBlock.Slots = new ReadOnlyCollection <SlotInfo>(paddedSlotInfo);
                children.Add(childBlock);
                Debug.Assert(totalSlots == child.NumBoolSlots + child.NumProjectedSlots,
                             "Number of required slots is different from what each node in the tree has?");
            }

            // We need to add the slots added by each child uniformly for others (as nulls) since this is a union operation.
            if (additionalChildSlots.Count != 0)
            {
                foreach (CqlBlock childBlock in children)
                {
                    SlotInfo[] childSlots = new SlotInfo[totalSlots + additionalChildSlots.Count];
                    childBlock.Slots.CopyTo(childSlots, 0);
                    int index = totalSlots;
                    foreach (var addtionalChildSlotInfo in additionalChildSlots)
                    {
                        var slotInfo = addtionalChildSlotInfo.Item2;
                        if (addtionalChildSlotInfo.Item1.Equals(childBlock))
                        {
                            childSlots[index] = new SlotInfo(true /* is required */, true /* is projected */, slotInfo.SlotValue, slotInfo.OutputMember);
                        }
                        else
                        {
                            childSlots[index] = new SlotInfo(true /* is required */, true /* is projected */,
                                                             new ConstantProjectedSlot(Constant.Null, slotInfo.OutputMember), slotInfo.OutputMember);
                        }
                        //move on to the next slot added by children.
                        index++;
                    }
                    childBlock.Slots = new ReadOnlyCollection <SlotInfo>(childSlots);
                }
            }

            // Create the slotInfos and then Union CqlBlock
            SlotInfo[] slotInfos = new SlotInfo[totalSlots + additionalChildSlots.Count];

            // We pick the slot references from the first child, just as convention
            // In a union, values come from both sides
            CqlBlock firstChild = children[0];

            for (int slotNum = 0; slotNum < totalSlots; slotNum++)
            {
                SlotInfo slotInfo = firstChild.Slots[slotNum];
                // A required slot is somehow projected by a child in Union, so set isProjected to be the same as isRequired.
                bool isRequired = requiredSlots[slotNum];
                slotInfos[slotNum] = new SlotInfo(isRequired, isRequired, slotInfo.SlotValue, slotInfo.OutputMember);
            }

            for (int slotNum = totalSlots; slotNum < totalSlots + additionalChildSlots.Count; slotNum++)
            {
                var aslot = firstChild.Slots[slotNum];
                slotInfos[slotNum] = new SlotInfo(true, true, aslot.SlotValue, aslot.OutputMember);
            }

            CqlBlock block = new UnionCqlBlock(slotInfos, children, identifiers, ++blockAliasNum);

            return(block);
        }
Ejemplo n.º 14
0
 internal StringBuilder AsUserString(StringBuilder builder, string blockAlias, IEnumerable <Constant> constants, MemberPath outputMember, bool skipIsNotNull)
 {
     return(ToStringHelper(builder, blockAlias, constants, outputMember, skipIsNotNull, true));
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Creates a case statement for the <paramref name="memberPath"/> with no clauses.
 /// </summary>
 internal CaseStatement(MemberPath memberPath)
 {
     m_memberPath = memberPath;
     m_clauses    = new List <WhenThen>();
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Given a set of positive <paramref name="constants"/> generates a simplified negated constant Cql expression.
        /// Examples:
        ///     - 7, NOT(7, NULL) means NOT(NULL)
        ///     - 7, 8, NOT(7, 8, 9, 10) means NOT(9, 10)
        /// </summary>
        private void AsCql(Action trueLiteral, Action varIsNotNull, Action <Constant> varNotEqualsTo, IEnumerable <Constant> constants, MemberPath outputMember, bool skipIsNotNull)
        {
            bool isNullable = outputMember.IsNullable;
            // Remove all the constants from negated and then print "x <> C1 .. AND x <> C2 .. AND x <> C3 ..."
            Set <Constant> negatedConstants = new Set <Constant>(this.Elements, Constant.EqualityComparer);

            foreach (Constant constant in constants)
            {
                if (constant.Equals(this))
                {
                    continue;
                }
                Debug.Assert(negatedConstants.Contains(constant), "Negated constant must contain all positive constants");
                negatedConstants.Remove(constant);
            }

            if (negatedConstants.Count == 0)
            {
                // All constants cancel out - emit True.
                trueLiteral();
            }
            else
            {
                bool hasNull = negatedConstants.Contains(Constant.Null);
                negatedConstants.Remove(Constant.Null);

                // We always add IS NOT NULL if the property is nullable (and we cannot skip IS NOT NULL).
                // Also, if the domain contains NOT NULL, we must add it.

                if (hasNull || (isNullable && !skipIsNotNull))
                {
                    varIsNotNull();
                }

                foreach (Constant constant in negatedConstants)
                {
                    varNotEqualsTo(constant);
                }
            }
        }
Ejemplo n.º 17
0
 internal bool IsProjectedConditionMember(MemberPath memberPath)
 {
     return(m_projectedConditionMembers.Contains(memberPath));
 }
Ejemplo n.º 18
0
        // effects: Returns an error record if the keys of the extent/associationSet being mapped  are
        // present in the projected slots of this query. Returns null
        // otherwise. ownerCell indicates the cell that owns this and
        // resourceString is a resource used for error messages
        internal ErrorLog.Record VerifyKeysPresent(Cell ownerCell, Func <object, object, string> formatEntitySetMessage,
                                                   Func <object, object, object, string> formatAssociationSetMessage, ViewGenErrorCode errorCode)
        {
            List <MemberPath> prefixes = new List <MemberPath>(1);
            // Keep track of the key corresponding to each prefix
            List <ExtentKey> keys = new List <ExtentKey>(1);

            if (Extent is EntitySet)
            {
                // For entity set just get the full path of the key properties
                MemberPath prefix = new MemberPath(Extent);
                prefixes.Add(prefix);
                EntityType       entityType    = (EntityType)Extent.ElementType;
                List <ExtentKey> entitySetKeys = ExtentKey.GetKeysForEntityType(prefix, entityType);
                Debug.Assert(entitySetKeys.Count == 1, "Currently, we only support primary keys");
                keys.Add(entitySetKeys[0]);
            }
            else
            {
                AssociationSet relationshipSet = (AssociationSet)Extent;
                // For association set, get the full path of the key
                // properties of each end

                foreach (AssociationSetEnd relationEnd in relationshipSet.AssociationSetEnds)
                {
                    AssociationEndMember assocEndMember = relationEnd.CorrespondingAssociationEndMember;
                    MemberPath           prefix         = new MemberPath(relationshipSet, assocEndMember);
                    prefixes.Add(prefix);
                    List <ExtentKey> endKeys = ExtentKey.GetKeysForEntityType(prefix,
                                                                              MetadataHelper.GetEntityTypeForEnd(assocEndMember));
                    Debug.Assert(endKeys.Count == 1, "Currently, we only support primary keys");
                    keys.Add(endKeys[0]);
                }
            }

            for (int i = 0; i < prefixes.Count; i++)
            {
                MemberPath prefix = prefixes[i];
                // Get all or none key slots that are being projected in this cell query
                List <MemberProjectedSlot> keySlots = MemberProjectedSlot.GetKeySlots(GetMemberProjectedSlots(), prefix);
                if (keySlots == null)
                {
                    ExtentKey key = keys[i];
                    string    message;
                    if (Extent is EntitySet)
                    {
                        string keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, true);
                        message = formatEntitySetMessage(keyPropertiesString, Extent.Name);
                    }
                    else
                    {
                        string endName             = prefix.RootEdmMember.Name;
                        string keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, false);
                        message = formatAssociationSetMessage(keyPropertiesString, endName, Extent.Name);
                    }
                    ErrorLog.Record error = new ErrorLog.Record(true, errorCode, message, ownerCell, String.Empty);
                    return(error);
                }
            }
            return(null);
        }
Ejemplo n.º 19
0
 internal bool IsConditionMember(MemberPath path)
 {
     return(m_conditionDomainMap.ContainsKey(path));
 }
        /// <summary>
        /// Given the <paramref name="outputMember"/> in the output extent view, generates a constructor expression for
        /// <paramref name="outputMember"/>'s type, i.e, an expression of the form "Type(....)"
        /// If <paramref name="outputMember"/> is an association end then instead of constructing an Entity or Complex type, constructs a reference.
        /// </summary>
        private void AsCql(Action <EntitySet, IList <MemberPath> > createRef, Action <IList <MemberPath> > createType, MemberPath outputMember)
        {
            EntitySet refScopeEntitySet = outputMember.GetScopeOfRelationEnd();

            if (refScopeEntitySet != null)
            {
                // Construct a scoped reference: CreateRef(CPerson1Set, NewRow(pid1, pid2), CPerson1)
                EntityType        entityType           = refScopeEntitySet.ElementType;
                List <MemberPath> keyMemberOutputPaths = new List <MemberPath>(entityType.KeyMembers.Select(km => new MemberPath(outputMember, km)));
                createRef(refScopeEntitySet, keyMemberOutputPaths);
            }
            else
            {
                // Construct an entity/complex/Association type in the Members order for fields: CPerson(CPerson1_Pid, CPerson1_Name)
                Debug.Assert(m_edmType is StructuralType, "m_edmType must be a structural type.");
                List <MemberPath> memberOutputPaths = new List <MemberPath>();
                foreach (EdmMember structuralMember in Helper.GetAllStructuralMembers(m_edmType))
                {
                    memberOutputPaths.Add(new MemberPath(outputMember, structuralMember));
                }
                createType(memberOutputPaths);
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Removes AllOtherConstant element from the domain set given by MemberPath
        /// </summary>
        internal void RemoveSentinel(MemberPath path)
        {
            CellConstantSet set = GetDomainInternal(path);

            set.Remove(Constant.AllOtherConstants);
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Not supported in this class.
 /// </summary>
 internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
 {
     Debug.Fail("Should not be called.");
     return(null); // To keep the compiler happy
 }
Ejemplo n.º 23
0
 // requires member exist in this
 // effects: Returns the possible values/domain for that member
 internal IEnumerable <Constant> GetDomain(MemberPath path)
 {
     return(GetDomainInternal(path));
 }
Ejemplo n.º 24
0
 /// <summary>
 /// Generates CQT for the constant expression.
 /// </summary>
 /// <param name="row">The input row.</param>
 /// <param name="outputMember">The member to which this constant is directed</param>
 internal abstract DbExpression AsCqt(DbExpression row, MemberPath outputMember);
Ejemplo n.º 25
0
 /// <summary>
 /// Creates a scalar member restriction with the meaning "<paramref name="member"/> = <paramref name="value"/>".
 /// This constructor is used for creating discriminator type conditions.
 /// </summary>
 internal ScalarRestriction(MemberPath member, Constant value)
     : base(new MemberProjectedSlot(member), value)
 {
     Debug.Assert(value is ScalarConstant || value.IsNull() || value.IsNotNull(), "value is expected to be ScalarConstant, NULL, or NOT_NULL.");
 }