private void AddCaseForOuterJoins(
            CaseStatement caseForOuterJoins,
            CqlBlock child,
            int slotNum,
            CqlIdentifiers identifiers)
        {
            ConstantProjectedSlot constantProjectedSlot = child.SlotValue(slotNum) as ConstantProjectedSlot;

            if (constantProjectedSlot != null && constantProjectedSlot.CellConstant.IsNull())
            {
                return;
            }
            BoolExpression or = BoolExpression.False;

            for (int index = 0; index < this.NumBoolSlots; ++index)
            {
                int slot = this.BoolIndexToSlot(index);
                if (child.IsProjected(slot))
                {
                    QualifiedCellIdBoolean qualifiedCellIdBoolean = new QualifiedCellIdBoolean(child, identifiers, index);
                    or = BoolExpression.CreateOr(or, BoolExpression.CreateLiteral((BoolLiteral)qualifiedCellIdBoolean, this.RightDomainMap));
                }
            }
            QualifiedSlot qualifiedSlot = child.QualifySlotWithBlockAlias(slotNum);

            caseForOuterJoins.AddWhenThen(or, (ProjectedSlot)qualifiedSlot);
        }
        private static int GetInnerJoinChildForSlot(List <CqlBlock> children, int slotNum)
        {
            int num = -1;

            for (int index = 0; index < children.Count; ++index)
            {
                CqlBlock child = children[index];
                if (child.IsProjected(slotNum))
                {
                    ProjectedSlot         projectedSlot         = child.SlotValue(slotNum);
                    ConstantProjectedSlot constantProjectedSlot = projectedSlot as ConstantProjectedSlot;
                    if (projectedSlot is MemberProjectedSlot)
                    {
                        num = index;
                    }
                    else if (constantProjectedSlot != null && constantProjectedSlot.CellConstant.IsNull())
                    {
                        if (num == -1)
                        {
                            num = index;
                        }
                    }
                    else
                    {
                        num = index;
                    }
                }
            }
            return(num);
        }
示例#3
0
        protected override bool IsEqualTo(ProjectedSlot right)
        {
            ConstantProjectedSlot constantProjectedSlot = right as ConstantProjectedSlot;

            if (constantProjectedSlot == null)
            {
                return(false);
            }
            return(Constant.EqualityComparer.Equals(this.m_constant, constantProjectedSlot.m_constant));
        }
        internal override CqlBlock ToCqlBlock(
            bool[] requiredSlots,
            CqlIdentifiers identifiers,
            ref int blockAliasNum,
            ref List <WithRelationship> withRelationships)
        {
            int       length         = requiredSlots.Length;
            CellQuery rightCellQuery = this.LeftCellWrapper.RightCellQuery;

            SlotInfo[] slotInfoArray = new SlotInfo[length];
            for (int index = 0; index < rightCellQuery.NumProjectedSlots; ++index)
            {
                ProjectedSlot slotValue = rightCellQuery.ProjectedSlotAt(index);
                if (requiredSlots[index] && slotValue == null)
                {
                    ConstantProjectedSlot slot = new ConstantProjectedSlot(Domain.GetDefaultValueForMemberPath(this.ProjectedSlotMap[index], (IEnumerable <LeftCellWrapper>) this.GetLeaves(), this.ViewgenContext.Config));
                    rightCellQuery.FixMissingSlotAsDefaultConstant(index, slot);
                    slotValue = (ProjectedSlot)slot;
                }
                SlotInfo slotInfo = new SlotInfo(requiredSlots[index], slotValue != null, slotValue, this.ProjectedSlotMap[index]);
                slotInfoArray[index] = slotInfo;
            }
            for (int index = 0; index < rightCellQuery.NumBoolVars; ++index)
            {
                BoolExpression       boolVar = rightCellQuery.GetBoolVar(index);
                BooleanProjectedSlot booleanProjectedSlot = boolVar == null ? new BooleanProjectedSlot(BoolExpression.False, identifiers, index) : new BooleanProjectedSlot(boolVar, identifiers, index);
                int      slot     = this.BoolIndexToSlot(index);
                SlotInfo slotInfo = new SlotInfo(requiredSlots[slot], boolVar != null, (ProjectedSlot)booleanProjectedSlot, (MemberPath)null);
                slotInfoArray[slot] = slotInfo;
            }
            IEnumerable <SlotInfo> source = (IEnumerable <SlotInfo>)slotInfoArray;

            if (rightCellQuery.Extent.EntityContainer.DataSpace == DataSpace.SSpace && this.m_cellWrapper.LeftExtent.BuiltInTypeKind == BuiltInTypeKind.EntitySet)
            {
                IEnumerable <AssociationSetMapping> relationshipSetMappingsFor = this.ViewgenContext.EntityContainerMapping.GetRelationshipSetMappingsFor(this.m_cellWrapper.LeftExtent, rightCellQuery.Extent);
                List <SlotInfo> foreignKeySlots = new List <SlotInfo>();
                foreach (AssociationSetMapping colocatedAssociationSetMap in relationshipSetMappingsFor)
                {
                    WithRelationship withRelationship;
                    if (LeafCellTreeNode.TryGetWithRelationship(colocatedAssociationSetMap, this.m_cellWrapper.LeftExtent, rightCellQuery.SourceExtentMemberPath, ref foreignKeySlots, out withRelationship))
                    {
                        withRelationships.Add(withRelationship);
                        source = ((IEnumerable <SlotInfo>)slotInfoArray).Concat <SlotInfo>((IEnumerable <SlotInfo>)foreignKeySlots);
                    }
                }
            }
            return((CqlBlock) new ExtentCqlBlock(rightCellQuery.Extent, rightCellQuery.SelectDistinctFlag, source.ToArray <SlotInfo>(), rightCellQuery.WhereClause, identifiers, ++blockAliasNum));
        }
        private static bool TryGetInstantiatedType(ProjectedSlot slot, out EdmType type)
        {
            type = (EdmType)null;
            ConstantProjectedSlot constantProjectedSlot = slot as ConstantProjectedSlot;

            if (constantProjectedSlot != null)
            {
                TypeConstant cellConstant = constantProjectedSlot.CellConstant as TypeConstant;
                if (cellConstant != null)
                {
                    type = cellConstant.EdmType;
                    return(true);
                }
            }
            return(false);
        }
        internal void Simplify()
        {
            if (this.m_simplified)
            {
                return;
            }
            List <CaseStatement.WhenThen> whenThenList = new List <CaseStatement.WhenThen>();
            bool flag = false;

            foreach (CaseStatement.WhenThen clause in this.m_clauses)
            {
                ConstantProjectedSlot constantProjectedSlot = clause.Value as ConstantProjectedSlot;
                if (constantProjectedSlot != null && (constantProjectedSlot.CellConstant.IsNull() || constantProjectedSlot.CellConstant.IsUndefined()))
                {
                    flag = true;
                }
                else
                {
                    whenThenList.Add(clause);
                    if (clause.Condition.IsTrue)
                    {
                        break;
                    }
                }
            }
            if (flag && whenThenList.Count == 0)
            {
                this.m_elseValue = (ProjectedSlot) new ConstantProjectedSlot(Constant.Null);
            }
            if (whenThenList.Count > 0 && !flag)
            {
                int index = whenThenList.Count - 1;
                this.m_elseValue = whenThenList[index].Value;
                whenThenList.RemoveAt(index);
            }
            this.m_clauses    = whenThenList;
            this.m_simplified = true;
        }
示例#7
0
 internal void FixMissingSlotAsDefaultConstant(int slotNumber, ConstantProjectedSlot slot)
 {
     Debug.Assert(m_projectedSlots[slotNumber] == null, "Another attempt to plug in a default value");
     m_projectedSlots[slotNumber] = slot;
 }
示例#8
0
 internal void FixMissingSlotAsDefaultConstant(int slotNumber, ConstantProjectedSlot slot)
 {
     Debug.Assert(m_projectedSlots[slotNumber] == null, "Another attempt to plug in a default value");
     m_projectedSlots[slotNumber] = slot;
 }
        internal override CqlBlock ToCqlBlock(
            bool[] requiredSlots, CqlIdentifiers identifiers, ref int blockAliasNum, ref List <WithRelationship> withRelationships)
        {
            // Get the projected slots and the boolean expressions
            var totalSlots = requiredSlots.Length;
            var cellQuery  = LeftCellWrapper.RightCellQuery;

            var 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 (var i = 0; i < cellQuery.NumProjectedSlots; i++)
            {
                var 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)
                {
                    var memberPath   = ProjectedSlotMap[i];
                    var defaultValue =
                        new ConstantProjectedSlot(Domain.GetDefaultValueForMemberPath(memberPath, GetLeaves(), ViewgenContext.Config));
                    cellQuery.FixMissingSlotAsDefaultConstant(i, defaultValue);
                    slot = defaultValue;
                }
                var slotInfo = new SlotInfo(
                    requiredSlots[i], slot != null,
                    slot, ProjectedSlotMap[i]);
                projectedSlots[i] = slotInfo;
            }

            // Add the boolean fields
            for (var boolNum = 0; boolNum < cellQuery.NumBoolVars; boolNum++)
            {
                var expr = cellQuery.GetBoolVar(boolNum);
                BooleanProjectedSlot boolSlot;
                if (expr != null)
                {
                    boolSlot = new BooleanProjectedSlot(expr, identifiers, boolNum);
                }
                else
                {
                    boolSlot = new BooleanProjectedSlot(BoolExpression.False, identifiers, boolNum);
                }
                var slotIndex = BoolIndexToSlot(boolNum);
                var 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) &&
                (m_cellWrapper.LeftExtent.BuiltInTypeKind == BuiltInTypeKind.EntitySet))
            {
                var associationSetMaps =
                    ViewgenContext.EntityContainerMapping.GetRelationshipSetMappingsFor(m_cellWrapper.LeftExtent, cellQuery.Extent);
                var foreignKeySlots = new List <SlotInfo>();
                foreach (var colocatedAssociationSetMap in associationSetMaps)
                {
                    WithRelationship withRelationship;
                    if (TryGetWithRelationship(
                            colocatedAssociationSetMap, m_cellWrapper.LeftExtent, cellQuery.SourceExtentMemberPath, ref foreignKeySlots,
                            out withRelationship))
                    {
                        withRelationships.Add(withRelationship);
                        totalProjectedSlots = projectedSlots.Concat(foreignKeySlots);
                    }
                }
            }
            var result = new ExtentCqlBlock(
                cellQuery.Extent, cellQuery.SelectDistinctFlag, totalProjectedSlots.ToArray(),
                cellQuery.WhereClause, identifiers, ++blockAliasNum);

            return(result);
        }
示例#10
0
        // returns true when the case statement is completed
        private bool AddRewritingToCaseStatement(
            Tile<FragmentQuery> rewriting, CaseStatement caseStatement, MemberPath currentPath, Constant domainValue)
        {
            var whenCondition = BoolExpression.True;
            // check whether the rewriting is always true or always false
            // if it's always true, we don't need any other WHEN clauses in the case statement
            // if it's always false, we don't need to add this WHEN clause to the case statement
            // given: domainQuery is satisfied. Check (domainQuery -> rewriting)
            var isAlwaysTrue = _qp.IsContainedIn(CreateTile(_domainQuery), rewriting);
            var isAlwaysFalse = _qp.IsDisjointFrom(CreateTile(_domainQuery), rewriting);
            Debug.Assert(!(isAlwaysTrue && isAlwaysFalse));
            if (isAlwaysFalse)
            {
                return false; // don't need an unsatisfiable WHEN clause
            }
            if (isAlwaysTrue)
            {
                Debug.Assert(caseStatement.Clauses.Count == 0);
            }

            ProjectedSlot projectedSlot;
            if (domainValue.HasNotNull())
            {
                projectedSlot = new MemberProjectedSlot(currentPath);
            }
            else
            {
                projectedSlot = new ConstantProjectedSlot(domainValue);
            }

            if (!isAlwaysTrue)
            {
                whenCondition = TileToBoolExpr(rewriting);
            }
            else
            {
                whenCondition = BoolExpression.True;
            }
            caseStatement.AddWhenThen(whenCondition, projectedSlot);

            return isAlwaysTrue;
        }
示例#11
0
        // 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
                var unrequiredSlotInfo = new SlotInfo(false, false, null, GetMemberPath(slotNum));
                return(unrequiredSlotInfo);
            }

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

            for (var childNum = 0; childNum < children.Count; childNum++)
            {
                var 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)
                        {
                            var 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;
                }
            }

            var           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));
                }
            }

            // 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.
            var 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
            var slotInfo = new SlotInfo(true, true, slot, memberPath, enforceNotNull);

            return(slotInfo);
        }
 internal void FixMissingSlotAsDefaultConstant(int slotNumber, ConstantProjectedSlot slot)
 {
     this.m_projectedSlots[slotNumber] = (ProjectedSlot)slot;
 }