internal override CellTreeNode VisitOpNode(OpCellTreeNode node, bool dummy)
            {
                var flattenedChildren = new List <CellTreeNode>();

                // Flatten the children first
                foreach (var child in node.Children)
                {
                    var flattenedChild = child.Accept(this, dummy);
                    flattenedChildren.Add(flattenedChild);
                }

                Debug.Assert(flattenedChildren.Count > 1, "node must have more than 1 child and be an OpCellTreeNode");

                // If this op is associative and a child's OP is the same as this
                // op, add those to be this nodes children
                var finalChildren = flattenedChildren;

                if (IsAssociativeOp(node.OpType))
                {
                    finalChildren = new List <CellTreeNode>();
                    foreach (var child in flattenedChildren)
                    {
                        if (child.OpType
                            == node.OpType)
                        {
                            finalChildren.AddRange(child.Children);
                        }
                        else
                        {
                            finalChildren.Add(child);
                        }
                    }
                }

                var result = new OpCellTreeNode(node.ViewgenContext, node.OpType, finalChildren);

                return(result);
            }
 internal override CellTreeNode VisitLeftAntiSemiJoin(OpCellTreeNode node, TInput param)
 {
     return(AcceptChildren(node, param));
 }
 internal override CellTreeNode VisitFullOuterJoin(OpCellTreeNode node, TInput param)
 {
     return(AcceptChildren(node, param));
 }
 internal abstract TOutput VisitOpNode(OpCellTreeNode node, TInput param);
 internal abstract TOutput VisitLeftAntiSemiJoin(OpCellTreeNode node, TInput param);
 internal abstract TOutput VisitFullOuterJoin(OpCellTreeNode node, TInput param);
 internal override CellTreeNode VisitLeftOuterJoin(
     OpCellTreeNode node,
     TInput param)
 {
     return((CellTreeNode)this.AcceptChildren(node, param));
 }
        private CqlBlock UnionToCqlBlock(
            bool[] requiredSlots,
            CqlIdentifiers identifiers,
            ref int blockAliasNum,
            ref List <WithRelationship> withRelationships)
        {
            List <CqlBlock> children = new List <CqlBlock>();
            List <Tuple <CqlBlock, SlotInfo> > tupleList = new List <Tuple <CqlBlock, SlotInfo> >();
            int length1 = requiredSlots.Length;

            foreach (CellTreeNode child in this.Children)
            {
                bool[] projectedSlots = child.GetProjectedSlots();
                OpCellTreeNode.AndWith(projectedSlots, requiredSlots);
                CqlBlock cqlBlock = child.ToCqlBlock(projectedSlots, identifiers, ref blockAliasNum, ref withRelationships);
                for (int length2 = projectedSlots.Length; length2 < cqlBlock.Slots.Count; ++length2)
                {
                    tupleList.Add(Tuple.Create <CqlBlock, SlotInfo>(cqlBlock, cqlBlock.Slots[length2]));
                }
                SlotInfo[] slotInfoArray = new SlotInfo[cqlBlock.Slots.Count];
                for (int slotNum = 0; slotNum < length1; ++slotNum)
                {
                    if (requiredSlots[slotNum] && !projectedSlots[slotNum])
                    {
                        if (this.IsBoolSlot(slotNum))
                        {
                            slotInfoArray[slotNum] = new SlotInfo(true, true, (ProjectedSlot) new BooleanProjectedSlot(BoolExpression.False, identifiers, this.SlotToBoolIndex(slotNum)), (MemberPath)null);
                        }
                        else
                        {
                            MemberPath outputMember = cqlBlock.MemberPath(slotNum);
                            slotInfoArray[slotNum] = new SlotInfo(true, true, (ProjectedSlot) new ConstantProjectedSlot(Constant.Null), outputMember);
                        }
                    }
                    else
                    {
                        slotInfoArray[slotNum] = cqlBlock.Slots[slotNum];
                    }
                }
                cqlBlock.Slots = new ReadOnlyCollection <SlotInfo>((IList <SlotInfo>)slotInfoArray);
                children.Add(cqlBlock);
            }
            if (tupleList.Count != 0)
            {
                foreach (CqlBlock cqlBlock in children)
                {
                    SlotInfo[] array = new SlotInfo[length1 + tupleList.Count];
                    cqlBlock.Slots.CopyTo(array, 0);
                    int index = length1;
                    foreach (Tuple <CqlBlock, SlotInfo> tuple in tupleList)
                    {
                        SlotInfo slotInfo = tuple.Item2;
                        array[index] = !tuple.Item1.Equals((object)cqlBlock) ? new SlotInfo(true, true, (ProjectedSlot) new ConstantProjectedSlot(Constant.Null), slotInfo.OutputMember) : new SlotInfo(true, true, slotInfo.SlotValue, slotInfo.OutputMember);
                        ++index;
                    }
                    cqlBlock.Slots = new ReadOnlyCollection <SlotInfo>((IList <SlotInfo>)array);
                }
            }
            SlotInfo[] slotInfos = new SlotInfo[length1 + tupleList.Count];
            CqlBlock   cqlBlock1 = children[0];

            for (int index = 0; index < length1; ++index)
            {
                SlotInfo slot         = cqlBlock1.Slots[index];
                bool     requiredSlot = requiredSlots[index];
                slotInfos[index] = new SlotInfo(requiredSlot, requiredSlot, slot.SlotValue, slot.OutputMember);
            }
            for (int index = length1; index < length1 + tupleList.Count; ++index)
            {
                SlotInfo slot = cqlBlock1.Slots[index];
                slotInfos[index] = new SlotInfo(true, true, slot.SlotValue, slot.OutputMember);
            }
            return((CqlBlock) new UnionCqlBlock(slotInfos, children, identifiers, ++blockAliasNum));
        }