Ejemplo n.º 1
0
        // <summary>
        // Creates a qualified slot "block_alias.slot_alias"
        // </summary>
        internal QualifiedSlot(CqlBlock block, ProjectedSlot slot)
        {
            DebugCheck.NotNull(block);
            DebugCheck.NotNull(slot);

            m_block = block;
            m_slot = slot; // Note: slot can be another qualified slot.
        }
 internal CaseCqlBlock(
     SlotInfo[] slots,
     int caseSlot,
     CqlBlock child,
     BoolExpression whereClause,
     CqlIdentifiers identifiers,
     int blockAliasNum)
     : base(slots, new List <CqlBlock>((IEnumerable <CqlBlock>) new CqlBlock[1]
 {
     child
 }), whereClause, identifiers, blockAliasNum)
 {
     this.m_caseSlotInfo = slots[caseSlot];
 }
 /// <summary>
 ///     Recursively qualifies all <see cref="ProjectedSlot" />s and returns a new deeply qualified
 ///     <see
 ///         cref="CaseStatement" />
 ///     .
 /// </summary>
 internal CaseStatement DeepQualify(CqlBlock block)
 {
     // Go through the whenthens and else and make a new case statement with qualified slots as needed.
     var result = new CaseStatement(m_memberPath);
     foreach (var whenThen in m_clauses)
     {
         var newClause = whenThen.ReplaceWithQualifiedSlot(block);
         result.m_clauses.Add(newClause);
     }
     if (m_elseValue != null)
     {
         result.m_elseValue = m_elseValue.DeepQualify(block);
     }
     result.m_simplified = m_simplified;
     return result;
 }
Ejemplo n.º 4
0
        internal override DbExpression AsCqt(bool isTopLevel)
        {
            CqlBlock      child1       = this.Children[0];
            DbExpression  dbExpression = child1.AsCqt(false);
            List <string> stringList   = new List <string>();

            for (int index = 1; index < this.Children.Count; ++index)
            {
                CqlBlock     child2 = this.Children[index];
                DbExpression right  = child2.AsCqt(false);
                Func <DbExpression, DbExpression, DbExpression> joinCondition = new Func <DbExpression, DbExpression, DbExpression>(this.m_onClauses[index - 1].AsCqt);
                DbJoinExpression dbJoinExpression;
                switch (this.m_opType)
                {
                case CellTreeOpType.FOJ:
                    dbJoinExpression = dbExpression.FullOuterJoin(right, joinCondition);
                    break;

                case CellTreeOpType.LOJ:
                    dbJoinExpression = dbExpression.LeftOuterJoin(right, joinCondition);
                    break;

                case CellTreeOpType.IJ:
                    dbJoinExpression = dbExpression.InnerJoin(right, joinCondition);
                    break;

                default:
                    return((DbExpression)null);
                }
                if (index == 1)
                {
                    child1.SetJoinTreeContext((IList <string>)stringList, dbJoinExpression.Left.VariableName);
                }
                else
                {
                    stringList.Add(dbJoinExpression.Left.VariableName);
                }
                child2.SetJoinTreeContext((IList <string>)stringList, dbJoinExpression.Right.VariableName);
                dbExpression = (DbExpression)dbJoinExpression;
            }
            return((DbExpression)dbExpression.Select <DbExpression>((Func <DbExpression, DbExpression>)(row => this.GenerateProjectionCqt(row, false))));
        }
Ejemplo n.º 5
0
        /// <summary>
        ///     Given the <paramref name="viewBlock" /> tree, generates the case statement blocks on top of it (using
        ///     <see
        ///         cref="m_caseStatements" />
        ///     ) and returns the resulting tree.
        ///     One block per case statement is generated. Generated blocks are nested, with the <paramref name="viewBlock" /> is the innermost input.
        /// </summary>
        private CqlBlock ConstructCaseBlocks(CqlBlock viewBlock, IEnumerable<WithRelationship> withRelationships)
        {
            // Get the 0th slot only, i.e., the extent
            var topSlots = new bool[TotalSlots];
            topSlots[0] = true;

            // all booleans in the top-level WHERE clause are required and get bubbled up
            // this makes some _fromX booleans be marked as 'required by parent'
            m_topLevelWhereClause.GetRequiredSlots(m_projectedSlotMap, topSlots);
            var result = ConstructCaseBlocks(viewBlock, 0, topSlots, withRelationships);
            return result;
        }
Ejemplo n.º 6
0
 // <summary>
 // Creates new <see cref="ProjectedSlot" /> that is qualified with <paramref name="block" />.CqlAlias.
 // If current slot is composite (such as <see cref="CaseStatementProjectedSlot" />, then this method recursively qualifies all parts
 // and returns a new deeply qualified slot (as opposed to <see cref="CqlBlock.QualifySlotWithBlockAlias" />).
 // </summary>
 internal override ProjectedSlot DeepQualify(CqlBlock block)
 {
     // We take the slot inside this and change the block
     var result = new QualifiedSlot(block, m_slot);
     return result;
 }
Ejemplo n.º 7
0
 internal CaseCqlBlock(
     SlotInfo[] slots, int caseSlot, CqlBlock child, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum)
     : base(slots, new List<CqlBlock>(new[] { child }), whereClause, identifiers, blockAliasNum)
 {
     m_caseSlotInfo = slots[caseSlot];
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Creates a qualified slot "block_alias.slot_alias"
 /// </summary>
 internal QualifiedSlot(CqlBlock block, ProjectedSlot slot)
 {
     Debug.Assert(block != null && slot != null, "Null input to QualifiedSlot constructor");
     m_block = block;
     m_slot = slot; // Note: slot can be another qualified slot.
 }
Ejemplo n.º 9
0
 internal QualifiedSlot(CqlBlock block, ProjectedSlot slot)
 {
     this.m_block = block;
     this.m_slot  = slot;
 }
 internal override ProjectedSlot DeepQualify(CqlBlock block)
 {
     return this; // Nothing to create
 }
 // <summary>
 // Creates new <see cref="ProjectedSlot" /> that is qualified with <paramref name="block" />.CqlAlias.
 // If current slot is composite (such as <see cref="CaseStatementProjectedSlot" />, then this method recursively qualifies all parts
 // and returns a new deeply qualified slot (as opposed to <see cref="CqlBlock.QualifySlotWithBlockAlias" />).
 // </summary>
 internal override ProjectedSlot DeepQualify(CqlBlock block)
 {
     var newStatement = m_caseStatement.DeepQualify(block);
     return new CaseStatementProjectedSlot(newStatement, null);
 }
Ejemplo n.º 12
0
 internal CaseCqlBlock(
     SlotInfo[] slots, int caseSlot, CqlBlock child, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum)
     : base(slots, new List <CqlBlock>(new[] { child }), whereClause, identifiers, blockAliasNum)
 {
     m_caseSlotInfo = slots[caseSlot];
 }
Ejemplo n.º 13
0
 /// <summary>
 ///     Creates a boolean of the form "<paramref name="block" />.<paramref name="originalCellNum" />".
 /// </summary>
 internal QualifiedCellIdBoolean(CqlBlock block, CqlIdentifiers identifiers, int originalCellNum)
     : base(identifiers, originalCellNum)
 {
     m_block = block;
 }
Ejemplo n.º 14
0
 internal override ProjectedSlot DeepQualify(CqlBlock block)
 {
     return((ProjectedSlot) new QualifiedSlot(block, this.m_slot));
 }
Ejemplo n.º 15
0
        /// <summary>
        ///     Given the <paramref name="viewBlock" /> tree generated by the cell merging process and the
        ///     <paramref
        ///         name="parentRequiredSlots" />
        ///     ,
        ///     generates the block tree for the case statement at or past the startSlotNum, i.e., only for case statements that are beyond startSlotNum.
        /// </summary>
        private CqlBlock ConstructCaseBlocks(
            CqlBlock viewBlock, int startSlotNum, bool[] parentRequiredSlots, IEnumerable<WithRelationship> withRelationships)
        {
            var numMembers = m_projectedSlotMap.Count;
            // Find the next slot for which we have a case statement, i.e.,
            // which was in the multiconstants
            var foundSlot = FindNextCaseStatementSlot(startSlotNum, parentRequiredSlots, numMembers);

            if (foundSlot == -1)
            {
                // We have bottomed out - no more slots to generate cases for
                // Just get the base view block
                return viewBlock;
            }

            // Compute the requiredSlots for this member, i.e., what slots are needed to produce this member.
            var thisMember = m_projectedSlotMap[foundSlot];
            var thisRequiredSlots = new bool[TotalSlots];
            GetRequiredSlotsForCaseMember(thisMember, thisRequiredSlots);
            Debug.Assert(
                thisRequiredSlots.Length == parentRequiredSlots.Length &&
                thisRequiredSlots.Length == TotalSlots,
                "Number of slots in array should not vary across blocks");

            // Merge parent's requirements with this requirements
            for (var i = 0; i < TotalSlots; i++)
            {
                // We do ask the children to generate the slot that we are
                // producing if it is available
                if (parentRequiredSlots[i])
                {
                    thisRequiredSlots[i] = true;
                }
            }

            // If current case statement depends on its slot value, then make sure the value is produced by the child block.
            var thisCaseStatement = m_caseStatements[thisMember];
            thisRequiredSlots[foundSlot] = thisCaseStatement.DependsOnMemberValue;

            // Recursively, determine the block tree for slots beyond foundSlot.
            var childBlock = ConstructCaseBlocks(viewBlock, foundSlot + 1, thisRequiredSlots, null);

            // For each slot, create a SlotInfo object
            var slotInfos = CreateSlotInfosForCaseStatement(
                parentRequiredSlots, foundSlot, childBlock, thisCaseStatement, withRelationships);
            m_currentBlockNum++;

            // We have a where clause only at the top level
            var whereClause = startSlotNum == 0 ? m_topLevelWhereClause : BoolExpression.True;
            if (startSlotNum == 0)
            {
                // only slot #0 is required by parent; reset all 'required by parent' booleans introduced above
                for (var i = 1; i < slotInfos.Length; i++)
                {
                    slotInfos[i].ResetIsRequiredByParent();
                }
            }

            var result = new CaseCqlBlock(slotInfos, foundSlot, childBlock, whereClause, m_identifiers, m_currentBlockNum);
            return result;
        }
Ejemplo n.º 16
0
        /// <summary>
        ///     Given the slot (<paramref name="foundSlot" />) and its corresponding case statement (
        ///     <paramref
        ///         name="thisCaseStatement" />
        ///     ),
        ///     generates the slotinfos for the cql block producing the case statement.
        /// </summary>
        private SlotInfo[] CreateSlotInfosForCaseStatement(
            bool[] parentRequiredSlots,
            int foundSlot,
            CqlBlock childBlock,
            CaseStatement thisCaseStatement,
            IEnumerable<WithRelationship> withRelationships)
        {
            var numSlotsAddedByChildBlock = childBlock.Slots.Count - TotalSlots;
            var slotInfos = new SlotInfo[TotalSlots + numSlotsAddedByChildBlock];
            for (var slotNum = 0; slotNum < TotalSlots; slotNum++)
            {
                var isProjected = childBlock.IsProjected(slotNum);
                var isRequiredByParent = parentRequiredSlots[slotNum];
                var slot = childBlock.SlotValue(slotNum);
                var outputMember = GetOutputMemberPath(slotNum);
                if (slotNum == foundSlot)
                {
                    // We need a case statement instead for this slot that we
                    // are handling right now
                    Debug.Assert(isRequiredByParent, "Case result not needed by parent");

                    // Get a case statement with all slots replaced by aliases slots
                    var newCaseStatement = thisCaseStatement.DeepQualify(childBlock);
                    slot = new CaseStatementProjectedSlot(newCaseStatement, withRelationships);
                    isProjected = true; // We are projecting this slot now
                }
                else if (isProjected && isRequiredByParent)
                {
                    // We only alias something that is needed and is being projected by the child.
                    // It is a qualified slot into the child block.
                    slot = childBlock.QualifySlotWithBlockAlias(slotNum);
                }
                // For slots, if it is not required by the parent, we want to
                // set the isRequiredByParent for this slot to be
                // false. Furthermore, we do not want to introduce any "NULL
                // AS something" at this stage for slots not being
                // projected. So if the child does not project that slot, we
                // declare it as not being required by the parent (if such a
                // NULL was needed, it would have been pushed all the way
                // down to a non-case block.
                // Essentially, from a Case statement's parent perspective,
                // it is saying "If you can produce a slot either by yourself
                // or your children, please do. Otherwise, do not concoct anything"
                var slotInfo = new SlotInfo(isRequiredByParent && isProjected, isProjected, slot, outputMember);
                slotInfos[slotNum] = slotInfo;
            }
            for (var i = TotalSlots; i < TotalSlots + numSlotsAddedByChildBlock; i++)
            {
                var childAddedSlot = childBlock.QualifySlotWithBlockAlias(i);
                slotInfos[i] = new SlotInfo(true, true, childAddedSlot, childBlock.MemberPath(i));
            }
            return slotInfos;
        }
Ejemplo n.º 17
0
 internal WhenThen ReplaceWithQualifiedSlot(CqlBlock block)
 {
     // Change the THEN part
     var newValue = m_value.DeepQualify(block);
     return new WhenThen(m_condition, newValue);
 }