internal override bool IsProjectedSlot(int slot)
        {
            CellQuery cellQuery = LeftCellWrapper.RightCellQuery;

            if (IsBoolSlot(slot))
            {
                return(cellQuery.GetBoolVar(SlotToBoolIndex(slot)) != null);
            }
            else
            {
                return(cellQuery.ProjectedSlotAt(slot) != null);
            }
        }
示例#2
0
        // requires: RightCellQuery.Extent corresponds to a relationship set
        // effects: Returns the ends to which the key of the corresponding
        // table (i.e., the left query) maps to in the relationship set. For
        // example, if RightCellQuery.Extent is OrderOrders and it maps to
        // <oid, otherOid> of table SOrders with key oid, this returns the
        // end to which oid is mapped. Similarly, if we have a link table
        // with the whole key mapped to two ends of the association set, it
        // returns both ends
        private Set <AssociationEndMember> GetEndsForTablePrimaryKey()
        {
            CellQuery rightQuery = RightCellQuery;
            Set <AssociationEndMember> result = new Set <AssociationEndMember>(EqualityComparer <AssociationEndMember> .Default);

            // Get the key slots for the table (they are in the slotMap) and
            // check for that slot on the C-side
            foreach (int keySlot in m_memberMaps.ProjectedSlotMap.KeySlots)
            {
                MemberProjectedSlot slot = (MemberProjectedSlot)rightQuery.ProjectedSlotAt(keySlot);
                MemberPath          path = slot.MemberPath;
                // See what end it maps to in the relationSet
                AssociationEndMember endMember = (AssociationEndMember)path.RootEdmMember;
                Debug.Assert(endMember != null, "Element in path before scalar path is not end property?");
                result.Add(endMember);
            }
            Debug.Assert(result != null, "No end found for keyslots of table?");
            return(result);
        }
示例#3
0
        // requires: this domainMap has been created for the C-side
        // effects: Fixes the mergedDomain map in this by merging entries
        // available in updateDomainMap
        internal static void PropagateUpdateDomainToQueryDomain(IEnumerable <Cell> cells, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap)
        {
            foreach (Cell cell in cells)
            {
                CellQuery cQuery = cell.CQuery;
                CellQuery sQuery = cell.SQuery;

                for (int i = 0; i < cQuery.NumProjectedSlots; i++)
                {
                    MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(i) as MemberProjectedSlot;
                    MemberProjectedSlot sSlot = sQuery.ProjectedSlotAt(i) as MemberProjectedSlot;

                    if (cSlot == null || sSlot == null)
                    {
                        continue;
                    }

                    // Get the domain for sSlot and merge with cSlot's
                    MemberPath      cPath   = cSlot.MemberPath;
                    MemberPath      sPath   = sSlot.MemberPath;
                    CellConstantSet cDomain = queryDomainMap.GetDomainInternal(cPath);
                    CellConstantSet sDomain = updateDomainMap.GetDomainInternal(sPath);

                    // skip NULL because if c-side member is nullable, it's already there, and otherwise can't be taken
                    // skip negated because negated values are translated in a special way
                    cDomain.Unite(sDomain.Where(constant => !constant.IsNull() && !(constant is NegatedConstant)));

                    if (updateDomainMap.IsConditionMember(sPath) && !queryDomainMap.IsConditionMember(cPath))
                    {
                        // record this member so KB knows we have to generate constraints for it
                        queryDomainMap.m_projectedConditionMembers.Add(cPath);
                    }
                }
            }

            ExpandNegationsInDomainMap(queryDomainMap.m_conditionDomainMap);
            ExpandNegationsInDomainMap(queryDomainMap.m_nonConditionDomainMap);
        }
示例#4
0
        ComputeConstantDomainSetsForSlotsInUpdateViews(IEnumerable <Cell> cells, EdmItemCollection edmItemCollection)
        {
            Dictionary <MemberPath, CellConstantSet> updateDomainMap = new Dictionary <MemberPath, CellConstantSet>(MemberPath.EqualityComparer);

            foreach (Cell cell in cells)
            {
                CellQuery cQuery = cell.CQuery;
                CellQuery sQuery = cell.SQuery;

                foreach (MemberProjectedSlot sSlot in sQuery.GetConjunctsFromWhereClause().Select(oneOfConst => oneOfConst.RestrictedMemberSlot))
                {
                    // obtain initial slot domain and restrict it if the slot has conditions


                    CellConstantSet restrictedDomain;
                    bool            wasDomainRestricted = GetRestrictedOrUnrestrictedDomain(sSlot, sQuery, edmItemCollection, out restrictedDomain);

                    // Suppose that we have a cell:
                    //      Proj(ID, A) WHERE(A=5) FROM E   =   Proj(ID, B) FROM T

                    // In the above cell, B on the S-side is 5 and we add that to its range. But if B had a restriction,
                    // we do not add 5. Note that do we not have a problem w.r.t. possibleValues since if A=5 and B=1, we have an
                    // empty cell -- we should catch that as an error. If A = 5 and B = 5 is present then restrictedDomain
                    // and domainValues are the same

                    // if no restriction on the S-side and the slot is projected then take the domain from the C-side
                    if (!wasDomainRestricted)
                    {
                        int projectedPosition = sQuery.GetProjectedPosition(sSlot);
                        if (projectedPosition >= 0)
                        {
                            // get the domain of the respective C-side slot
                            MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(projectedPosition) as MemberProjectedSlot;
                            Debug.Assert(cSlot != null, "Assuming constants are not projected");

                            wasDomainRestricted = GetRestrictedOrUnrestrictedDomain(cSlot, cQuery, edmItemCollection, out restrictedDomain);

                            if (!wasDomainRestricted)
                            {
                                continue;
                            }
                        }
                    }

                    // Add the default value to the domain
                    MemberPath sSlotMemberPath = sSlot.MemberPath;
                    Constant   defaultValue;
                    if (TryGetDefaultValueForMemberPath(sSlotMemberPath, out defaultValue))
                    {
                        restrictedDomain.Add(defaultValue);
                    }

                    // add all constants appearing in the domain to sDomainMap
                    CellConstantSet sSlotDomain;
                    if (!updateDomainMap.TryGetValue(sSlotMemberPath, out sSlotDomain))
                    {
                        updateDomainMap[sSlotMemberPath] = restrictedDomain;
                    }
                    else
                    {
                        sSlotDomain.AddRange(restrictedDomain);
                    }
                }
            }
            return(updateDomainMap);
        }
        internal override CqlBlock ToCqlBlock(bool[] requiredSlots, CqlIdentifiers identifiers, ref int blockAliasNum, ref List <WithRelationship> withRelationships)
        {
            // Get the projected slots and the boolean expressions
            int       totalSlots = requiredSlots.Length;
            CellQuery cellQuery  = LeftCellWrapper.RightCellQuery;

            SlotInfo[] projectedSlots = new SlotInfo[totalSlots];
            Debug.Assert(cellQuery.NumProjectedSlots + cellQuery.NumBoolVars == totalSlots,
                         "Wrong number of projected slots in node");

            Debug.Assert(cellQuery.NumProjectedSlots == ProjectedSlotMap.Count,
                         "Different number of slots in cell query and what we have mappings for");
            // Add the regular fields
            for (int i = 0; i < cellQuery.NumProjectedSlots; i++)
            {
                ProjectedSlot slot = cellQuery.ProjectedSlotAt(i);
                // If the slot is not null, we will project it
                // For extents, we say that all requiredlots are the only the
                // ones that are CLR non-null. Recall that "real" nulls are
                // handled by having a CellConstant.Null in ConstantSlot
                if (requiredSlots[i] && slot == null)
                {
                    MemberPath            memberPath   = ProjectedSlotMap[i];
                    ConstantProjectedSlot defaultValue = new ConstantProjectedSlot(Domain.GetDefaultValueForMemberPath(memberPath, GetLeaves(), ViewgenContext.Config), memberPath);
                    cellQuery.FixMissingSlotAsDefaultConstant(i, defaultValue);
                    slot = defaultValue;
                }
                SlotInfo slotInfo = new SlotInfo(requiredSlots[i], slot != null,
                                                 slot, ProjectedSlotMap[i]);
                projectedSlots[i] = slotInfo;
            }

            // Add the boolean fields
            for (int boolNum = 0; boolNum < cellQuery.NumBoolVars; boolNum++)
            {
                BoolExpression       expr = cellQuery.GetBoolVar(boolNum);
                BooleanProjectedSlot boolSlot;
                if (expr != null)
                {
                    boolSlot = new BooleanProjectedSlot(expr, identifiers, boolNum);
                }
                else
                {
                    boolSlot = new BooleanProjectedSlot(BoolExpression.False, identifiers, boolNum);
                }
                int      slotIndex = BoolIndexToSlot(boolNum);
                SlotInfo slotInfo  = new SlotInfo(requiredSlots[slotIndex], expr != null,
                                                  boolSlot, null);
                projectedSlots[slotIndex] = slotInfo;
            }

            // See if we are generating a query view and whether there are any colocated foreign keys for which
            // we have to add With statements.
            IEnumerable <SlotInfo> totalProjectedSlots = projectedSlots;

            if ((cellQuery.Extent.EntityContainer.DataSpace == DataSpace.SSpace) &&
                (this.m_cellWrapper.LeftExtent.BuiltInTypeKind == BuiltInTypeKind.EntitySet))
            {
                IEnumerable <StorageAssociationSetMapping> associationSetMaps =
                    this.ViewgenContext.EntityContainerMapping.GetRelationshipSetMappingsFor(this.m_cellWrapper.LeftExtent, cellQuery.Extent);
                List <SlotInfo> foreignKeySlots = new List <SlotInfo>();
                foreach (StorageAssociationSetMapping colocatedAssociationSetMap in associationSetMaps)
                {
                    WithRelationship withRelationship;
                    if (TryGetWithRelationship(colocatedAssociationSetMap, this.m_cellWrapper.LeftExtent, cellQuery.SourceExtentMemberPath, ref foreignKeySlots, out withRelationship))
                    {
                        withRelationships.Add(withRelationship);
                        totalProjectedSlots = projectedSlots.Concat(foreignKeySlots);
                    }
                }
            }
            ExtentCqlBlock result = new ExtentCqlBlock(cellQuery.Extent, cellQuery.SelectDistinctFlag, totalProjectedSlots.ToArray(),
                                                       cellQuery.WhereClause, identifiers, ++blockAliasNum);

            return(result);
        }