Example #1
0
        // requires: caseForOuterJoins corresponds the slot "slotNum"
        // effects: Adds a WhenThen corresponding to child to caseForOuterJoins.
        private void AddCaseForOuterJoins(CaseStatement caseForOuterJoins, CqlBlock child, int slotNum, CqlIdentifiers identifiers)
        {
            // Determine the cells that the slot comes from
            // and make an OR expression, e.g., WHEN _from0 or _from2 or ... THEN child[slotNum]

            ProjectedSlot         childSlot    = child.SlotValue(slotNum);
            ConstantProjectedSlot constantSlot = childSlot as ConstantProjectedSlot;

            if (constantSlot != null && constantSlot.CellConstant.IsNull())
            {
                // NULL being generated by a child - don't need to project
                return;
            }

            BoolExpression originBool = BoolExpression.False;

            for (int i = 0; i < NumBoolSlots; i++)
            {
                int boolSlotNum = BoolIndexToSlot(i);
                if (child.IsProjected(boolSlotNum))
                {
                    // OR it to the expression
                    QualifiedCellIdBoolean boolExpr = new QualifiedCellIdBoolean(child, identifiers, i);
                    originBool = BoolExpression.CreateOr(originBool, BoolExpression.CreateLiteral(boolExpr, RightDomainMap));
                }
            }
            // Qualify the slotNum with the child.CqlAlias for the THEN
            QualifiedSlot slot = child.QualifySlotWithBlockAlias(slotNum);

            caseForOuterJoins.AddWhenThen(originBool, slot);
        }
Example #2
0
        private SlotInfo[] CreateSlotInfosForCaseStatement(
            bool[] parentRequiredSlots,
            int foundSlot,
            CqlBlock childBlock,
            CaseStatement thisCaseStatement,
            IEnumerable <WithRelationship> withRelationships)
        {
            int num = childBlock.Slots.Count - this.TotalSlots;

            SlotInfo[] slotInfoArray = new SlotInfo[this.TotalSlots + num];
            for (int slotNum = 0; slotNum < this.TotalSlots; ++slotNum)
            {
                bool          isProjected        = childBlock.IsProjected(slotNum);
                bool          parentRequiredSlot = parentRequiredSlots[slotNum];
                ProjectedSlot slotValue          = childBlock.SlotValue(slotNum);
                MemberPath    outputMemberPath   = this.GetOutputMemberPath(slotNum);
                if (slotNum == foundSlot)
                {
                    slotValue   = (ProjectedSlot) new CaseStatementProjectedSlot(thisCaseStatement.DeepQualify(childBlock), withRelationships);
                    isProjected = true;
                }
                else if (isProjected && parentRequiredSlot)
                {
                    slotValue = (ProjectedSlot)childBlock.QualifySlotWithBlockAlias(slotNum);
                }
                SlotInfo slotInfo = new SlotInfo(parentRequiredSlot && isProjected, isProjected, slotValue, outputMemberPath);
                slotInfoArray[slotNum] = slotInfo;
            }
            for (int totalSlots = this.TotalSlots; totalSlots < this.TotalSlots + num; ++totalSlots)
            {
                QualifiedSlot qualifiedSlot = childBlock.QualifySlotWithBlockAlias(totalSlots);
                slotInfoArray[totalSlots] = new SlotInfo(true, true, (ProjectedSlot)qualifiedSlot, childBlock.MemberPath(totalSlots));
            }
            return(slotInfoArray);
        }
        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 CqlBlock JoinToCqlBlock(
            bool[] requiredSlots,
            CqlIdentifiers identifiers,
            ref int blockAliasNum,
            ref List <WithRelationship> withRelationships)
        {
            int             length1  = requiredSlots.Length;
            List <CqlBlock> children = new List <CqlBlock>();
            List <Tuple <QualifiedSlot, MemberPath> > tupleList = new List <Tuple <QualifiedSlot, MemberPath> >();

            foreach (CellTreeNode child in this.Children)
            {
                bool[] projectedSlots = child.GetProjectedSlots();
                OpCellTreeNode.AndWith(projectedSlots, requiredSlots);
                CqlBlock cqlBlock = child.ToCqlBlock(projectedSlots, identifiers, ref blockAliasNum, ref withRelationships);
                children.Add(cqlBlock);
                for (int length2 = projectedSlots.Length; length2 < cqlBlock.Slots.Count; ++length2)
                {
                    tupleList.Add(Tuple.Create <QualifiedSlot, MemberPath>(cqlBlock.QualifySlotWithBlockAlias(length2), cqlBlock.MemberPath(length2)));
                }
            }
            SlotInfo[] slotInfos = new SlotInfo[length1 + tupleList.Count];
            for (int slotNum = 0; slotNum < length1; ++slotNum)
            {
                SlotInfo joinSlotInfo = this.GetJoinSlotInfo(this.OpType, requiredSlots[slotNum], children, slotNum, identifiers);
                slotInfos[slotNum] = joinSlotInfo;
            }
            int index1 = 0;
            int index2 = length1;

            while (index2 < length1 + tupleList.Count)
            {
                slotInfos[index2] = new SlotInfo(true, true, (ProjectedSlot)tupleList[index1].Item1, tupleList[index1].Item2);
                ++index2;
                ++index1;
            }
            List <JoinCqlBlock.OnClause> onClauses = new List <JoinCqlBlock.OnClause>();

            for (int index3 = 1; index3 < children.Count; ++index3)
            {
                CqlBlock cqlBlock = children[index3];
                JoinCqlBlock.OnClause onClause = new JoinCqlBlock.OnClause();
                foreach (int keySlot in this.KeySlots)
                {
                    if (!this.ViewgenContext.Config.IsValidationEnabled && (!cqlBlock.IsProjected(keySlot) || !children[0].IsProjected(keySlot)))
                    {
                        ErrorLog errorLog = new ErrorLog();
                        errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.NoJoinKeyOrFKProvidedInMapping, Strings.Viewgen_NoJoinKeyOrFK, (IEnumerable <LeftCellWrapper>) this.ViewgenContext.AllWrappersForExtent, string.Empty));
                        ExceptionHelpers.ThrowMappingException(errorLog, this.ViewgenContext.Config);
                    }
                    QualifiedSlot leftSlot     = children[0].QualifySlotWithBlockAlias(keySlot);
                    QualifiedSlot rightSlot    = cqlBlock.QualifySlotWithBlockAlias(keySlot);
                    MemberPath    outputMember = slotInfos[keySlot].OutputMember;
                    onClause.Add(leftSlot, outputMember, rightSlot, outputMember);
                }
                onClauses.Add(onClause);
            }
            return((CqlBlock) new JoinCqlBlock(this.OpType, slotInfos, children, onClauses, identifiers, ++blockAliasNum));
        }
Example #5
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)
        {
            int numSlotsAddedByChildBlock = childBlock.Slots.Count - TotalSlots;

            SlotInfo[] slotInfos = new SlotInfo[TotalSlots + numSlotsAddedByChildBlock];
            for (int slotNum = 0; slotNum < TotalSlots; slotNum++)
            {
                bool          isProjected        = childBlock.IsProjected(slotNum);
                bool          isRequiredByParent = parentRequiredSlots[slotNum];
                ProjectedSlot slot         = childBlock.SlotValue(slotNum);
                MemberPath    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
                    CaseStatement 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"
                SlotInfo slotInfo = new SlotInfo(isRequiredByParent && isProjected, isProjected, slot, outputMember);
                slotInfos[slotNum] = slotInfo;
            }
            for (int i = TotalSlots; i < TotalSlots + numSlotsAddedByChildBlock; i++)
            {
                QualifiedSlot childAddedSlot = childBlock.QualifySlotWithBlockAlias(i);
                slotInfos[i] = new SlotInfo(true, true, childAddedSlot, childBlock.MemberPath(i));
            }
            return(slotInfos);
        }
Example #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 virtual ProjectedSlot DeepQualify(CqlBlock block)
        {
            QualifiedSlot result = new QualifiedSlot(block, this);

            return(result);
        }