/// <summary> /// Initializes a <see cref="CqlBlock"/> with the SELECT (<paramref name="slotInfos"/>), FROM (<paramref name="children"/>), /// WHERE (<paramref name="whereClause"/>), AS (<paramref name="blockAliasNum"/>). /// </summary> protected CqlBlock(SlotInfo[] slotInfos, List<CqlBlock> children, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum) { m_slots = new ReadOnlyCollection<SlotInfo>(slotInfos); m_children = new ReadOnlyCollection<CqlBlock>(children); m_whereClause = whereClause; m_blockAlias = identifiers.GetBlockAlias(blockAliasNum); }
/// <summary> /// Creates a join block (type given by <paramref name="opType"/>) with SELECT (<paramref name="slotInfos"/>), FROM (<paramref name="children"/>), /// ON (<paramref name="onClauses"/> - one for each child except 0th), WHERE (true), AS (<paramref name="blockAliasNum"/>). /// </summary> internal JoinCqlBlock(CellTreeOpType opType, SlotInfo[] slotInfos, List<CqlBlock> children, List<OnClause> onClauses, CqlIdentifiers identifiers, int blockAliasNum) : base(slotInfos, children, BoolExpression.True, identifiers, blockAliasNum) { m_opType = opType; m_onClauses = onClauses; }
/// <summary> /// Creates an cql block representing the <paramref name="extent"/> (the FROM part). /// SELECT is given by <paramref name="slots"/>, WHERE by <paramref name="whereClause"/> and AS by <paramref name="blockAliasNum"/>. /// </summary> internal ExtentCqlBlock(EntitySetBase extent, CellQuery.SelectDistinct selectDistinct, SlotInfo[] slots, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum) : base(slots, EmptyChildren, whereClause, identifiers, blockAliasNum) { m_extent = extent; m_nodeTableAlias = identifiers.GetBlockAlias(); m_selectDistinct = selectDistinct; }
/// <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; }
/// <summary> /// Creates a <see cref="CqlBlock"/> containing the case statememt for the <paramref name="caseSlot"/> and projecting other slots as is from its child (input). CqlBlock with SELECT (slots), /// </summary> /// <param name="caseSlot">indicates which slot in <paramref name="slots"/> corresponds to the case statement being generated by this block</param> internal CaseCqlBlock(SlotInfo[] slots, int caseSlot, CqlBlock child, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum) : base(slots, new List<CqlBlock>(new CqlBlock[] { child }), whereClause, identifiers, blockAliasNum) { m_caseSlotInfo = slots[caseSlot]; }
/// <summary> /// Creates a union block with SELECT (<paramref name="slotInfos"/>), FROM (<paramref name="children"/>), WHERE (true), AS (<paramref name="blockAliasNum"/>). /// </summary> internal UnionCqlBlock(SlotInfo[] slotInfos, List<CqlBlock> children, CqlIdentifiers identifiers, int blockAliasNum) : base(slotInfos, children, BoolExpression.True, identifiers, blockAliasNum) { }