public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            base.VisitJoinAlgebraNode(node);

            if (node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
            {
                // TODO: Check if we could represent this join condition by an hash match operator

                JoinAlgebraNode leftOuterJoinNode = new JoinAlgebraNode();
                leftOuterJoinNode.Op         = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                leftOuterJoinNode.Predicate  = (ExpressionNode)node.Predicate.Clone();
                leftOuterJoinNode.Left       = (AlgebraNode)node.Left.Clone();
                leftOuterJoinNode.Right      = (AlgebraNode)node.Right.Clone();
                leftOuterJoinNode.OutputList = ArrayHelpers.Clone(node.OutputList);

                List <RowBufferEntry> swappedOutputList = new List <RowBufferEntry>();
                swappedOutputList.AddRange(node.Right.OutputList);
                swappedOutputList.AddRange(node.Left.OutputList);

                JoinAlgebraNode leftAntiSemiJoinNode = new JoinAlgebraNode();
                leftAntiSemiJoinNode.Op         = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin;
                leftAntiSemiJoinNode.Predicate  = (ExpressionNode)node.Predicate.Clone();
                leftAntiSemiJoinNode.Left       = (AlgebraNode)node.Right.Clone();
                leftAntiSemiJoinNode.Right      = (AlgebraNode)node.Left.Clone();
                leftAntiSemiJoinNode.OutputList = swappedOutputList.ToArray();

                List <ComputedValueDefinition> computeScalareDefinedValues = new List <ComputedValueDefinition>();
                foreach (RowBufferEntry rowBufferEntry in node.Left.OutputList)
                {
                    ComputedValueDefinition definedValue = new ComputedValueDefinition();
                    definedValue.Target     = rowBufferEntry;
                    definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType);
                    computeScalareDefinedValues.Add(definedValue);
                }

                ComputeScalarAlgebraNode computeScalarNode = new ComputeScalarAlgebraNode();
                computeScalarNode.Input         = leftAntiSemiJoinNode;
                computeScalarNode.DefinedValues = computeScalareDefinedValues.ToArray();
                computeScalarNode.OutputList    = swappedOutputList.ToArray();

                List <UnitedValueDefinition> concatDefinedValues = new List <UnitedValueDefinition>();
                for (int i = 0; i < node.OutputList.Length; i++)
                {
                    RowBufferEntry        rowBufferEntry     = node.OutputList[i];
                    UnitedValueDefinition concatDefinedValue = new UnitedValueDefinition();
                    concatDefinedValue.Target           = rowBufferEntry;
                    concatDefinedValue.DependendEntries = new RowBufferEntry[] { node.OutputList[i], node.OutputList[i] };
                    concatDefinedValues.Add(concatDefinedValue);
                }

                ConcatAlgebraNode concatenationNode = new ConcatAlgebraNode();
                concatenationNode.Inputs        = new AlgebraNode[] { leftOuterJoinNode, computeScalarNode };
                concatenationNode.DefinedValues = concatDefinedValues.ToArray();
                concatenationNode.OutputList    = swappedOutputList.ToArray();

                return(concatenationNode);
            }

            return(node);
        }
Example #2
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			base.VisitJoinAlgebraNode(node);

			if (node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
			{
				// TODO: Check if we could represent this join condition by an hash match operator

				JoinAlgebraNode leftOuterJoinNode = new JoinAlgebraNode();
				leftOuterJoinNode.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
				leftOuterJoinNode.Predicate = (ExpressionNode)node.Predicate.Clone();
				leftOuterJoinNode.Left = (AlgebraNode) node.Left.Clone();
				leftOuterJoinNode.Right = (AlgebraNode) node.Right.Clone();
				leftOuterJoinNode.OutputList = ArrayHelpers.Clone(node.OutputList);

				List<RowBufferEntry> swappedOutputList = new List<RowBufferEntry>();
				swappedOutputList.AddRange(node.Right.OutputList);
				swappedOutputList.AddRange(node.Left.OutputList);

				JoinAlgebraNode leftAntiSemiJoinNode = new JoinAlgebraNode();
				leftAntiSemiJoinNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin;
				leftAntiSemiJoinNode.Predicate = (ExpressionNode) node.Predicate.Clone();
				leftAntiSemiJoinNode.Left = (AlgebraNode) node.Right.Clone();
				leftAntiSemiJoinNode.Right = (AlgebraNode) node.Left.Clone();
				leftAntiSemiJoinNode.OutputList = swappedOutputList.ToArray();

				List<ComputedValueDefinition> computeScalareDefinedValues = new List<ComputedValueDefinition>();
				foreach (RowBufferEntry rowBufferEntry in node.Left.OutputList)
				{
					ComputedValueDefinition definedValue = new ComputedValueDefinition();
					definedValue.Target = rowBufferEntry;
					definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType);
					computeScalareDefinedValues.Add(definedValue);
				}

				ComputeScalarAlgebraNode computeScalarNode = new ComputeScalarAlgebraNode();
				computeScalarNode.Input = leftAntiSemiJoinNode;
				computeScalarNode.DefinedValues = computeScalareDefinedValues.ToArray();
				computeScalarNode.OutputList = swappedOutputList.ToArray();

				List<UnitedValueDefinition> concatDefinedValues = new List<UnitedValueDefinition>();
				for (int i = 0; i < node.OutputList.Length; i++)
				{
					RowBufferEntry rowBufferEntry = node.OutputList[i];
					UnitedValueDefinition concatDefinedValue = new UnitedValueDefinition();
					concatDefinedValue.Target = rowBufferEntry;
					concatDefinedValue.DependendEntries = new RowBufferEntry[] { node.OutputList[i], node.OutputList[i] };
					concatDefinedValues.Add(concatDefinedValue);
				}

				ConcatAlgebraNode concatenationNode = new ConcatAlgebraNode();
				concatenationNode.Inputs = new AlgebraNode[] {leftOuterJoinNode, computeScalarNode};
				concatenationNode.DefinedValues = concatDefinedValues.ToArray();
				concatenationNode.OutputList = swappedOutputList.ToArray();

				return concatenationNode;
			}

			return node;
		}
Example #3
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            for (int i = 0; i < node.Inputs.Length; i++)
                node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]);

            node.OutputList = GetRowBufferEntries(node.DefinedValues);
            return node;
        }
Example #4
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            base.VisitConcatAlgebraNode(node);

            foreach (UnitedValueDefinition definedValue in node.DefinedValues)
                ReplaceRowBufferEntries(definedValue.DependendEntries);

            return node;
        }
Example #5
0
        public virtual AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            for (int i = 0; i < node.Inputs.Length; i++)
            {
                node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]);
            }

            return(node);
        }
Example #6
0
		public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements)
		{
			ConcatAlgebraNode result = new ConcatAlgebraNode();
			result.StatisticsIterator = StatisticsIterator;
			result.OutputList = ArrayHelpers.Clone(OutputList);
			result.Inputs = ArrayHelpers.CreateDeepCopyOfAstElementArray(_inputs, alreadyClonedElements);
			result.DefinedValues = ArrayHelpers.CreateDeepCopyOfAstElementArray(_definedValues, alreadyClonedElements);
			return result;
		}
Example #7
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            base.VisitConcatAlgebraNode(node);

            foreach (UnitedValueDefinition definedValue in node.DefinedValues)
                NameEntry(definedValue.Target, UNION_NAME_FMT_STR);

            return node;
        }
Example #8
0
		public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
		{
			foreach (AlgebraNode input in node.Inputs)
				Visit(input);

			if (node.DefinedValues != null)
				AddDefinedValues(node.DefinedValues);

			return node;
		}
Example #9
0
        public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements)
        {
            ConcatAlgebraNode result = new ConcatAlgebraNode();

            result.StatisticsIterator = StatisticsIterator;
            result.OutputList         = ArrayHelpers.Clone(OutputList);
            result.Inputs             = ArrayHelpers.CreateDeepCopyOfAstElementArray(_inputs, alreadyClonedElements);
            result.DefinedValues      = ArrayHelpers.CreateDeepCopyOfAstElementArray(_definedValues, alreadyClonedElements);
            return(result);
        }
Example #10
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            for (int i = 0; i < node.Inputs.Length; i++)
            {
                node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]);
            }

            node.OutputList = GetRowBufferEntries(node.DefinedValues);
            return(node);
        }
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            base.VisitConcatAlgebraNode(node);

            foreach (UnitedValueDefinition definedValue in node.DefinedValues)
            {
                NameEntry(definedValue.Target, UNION_NAME_FMT_STR);
            }

            return(node);
        }
Example #12
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            base.VisitConcatAlgebraNode(node);

            foreach (UnitedValueDefinition definedValue in node.DefinedValues)
            {
                ReplaceRowBufferEntries(definedValue.DependendEntries);
            }

            return(node);
        }
Example #13
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            _xmlWriter.WriteStartElement("concatAlgebraNode");

            for (int i = 0; i < node.Inputs.Length; i++)
            {
                Visit(node.Inputs[i]);
            }

            _xmlWriter.WriteEndElement();

            return(node);
        }
Example #14
0
            public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
            {
                base.VisitConcatAlgebraNode(node);

                foreach (UnitedValueDefinition definedValue in node.DefinedValues)
                {
                    for (int i = 0; i < definedValue.DependendEntries.Length; i++)
                    {
                        definedValue.DependendEntries[i] = ReplaceRowBuffer(definedValue.DependendEntries[i]);
                    }
                }

                return(node);
            }
Example #15
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            foreach (AlgebraNode input in node.Inputs)
            {
                Visit(input);
            }

            if (node.DefinedValues != null)
            {
                AddDefinedValues(node.DefinedValues);
            }

            return(node);
        }
Example #16
0
        private AlgebraNode PushOverConcat(FilterAlgebraNode node)
        {
            ConcatAlgebraNode inputNode = (ConcatAlgebraNode)node.Input;

            for (int i = 0; i < inputNode.Inputs.Length; i++)
            {
                ExpressionNode predicate = (ExpressionNode)node.Predicate.Clone();
                ConcatRowBufferEntryReplacer concatRowBufferEntryReplacer = new ConcatRowBufferEntryReplacer(inputNode.DefinedValues, i);
                predicate = concatRowBufferEntryReplacer.VisitExpression(predicate);

                FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                filterAlgebraNode.Input     = inputNode.Inputs[i];
                filterAlgebraNode.Predicate = predicate;
                inputNode.Inputs[i]         = VisitAlgebraNode(filterAlgebraNode);
            }

            return(inputNode);
        }
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            node.OutputList = RemovedUnneededRowBufferColumns(node.OutputList);

            List <UnitedValueDefinition> definedValues = new List <UnitedValueDefinition>();

            foreach (UnitedValueDefinition definedValue in node.DefinedValues)
            {
                if (IsNeeded(definedValue.Target))
                {
                    definedValues.Add(definedValue);
                    foreach (RowBufferEntry dependendValue in definedValue.DependendEntries)
                    {
                        AddNeededRowBufferEntry(dependendValue);
                    }
                }
            }
            node.DefinedValues = definedValues.ToArray();
            node.OutputList    = GetRowBufferEntries(node.DefinedValues);
            return(base.VisitConcatAlgebraNode(node));
        }
Example #18
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            List <ShowPlanElement> inputList = new List <ShowPlanElement>();

            foreach (AlgebraNode inputNode in node.Inputs)
            {
                inputList.Add(ConvertNode(inputNode));
            }

            PropertyListBuilder propertyListBuilder = new PropertyListBuilder();

            AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOutputList, node.OutputList);
            AddStatistics(propertyListBuilder, node.StatisticsIterator);
            AddDefinedValues(propertyListBuilder, node.DefinedValues);

            IList <ShowPlanProperty> properties = propertyListBuilder.ToList();

            ShowPlanElement element = new ShowPlanElement(ShowPlanOperator.Concatenation, properties, inputList.ToArray());

            _currentElement = element;

            return(node);
        }
Example #19
0
			public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
			{
				base.VisitConcatAlgebraNode(node);

				foreach (UnitedValueDefinition definedValue in node.DefinedValues)
				{
					for (int i = 0; i < definedValue.DependendEntries.Length; i++)
						definedValue.DependendEntries[i] = ReplaceRowBuffer(definedValue.DependendEntries[i]);
				}

				return node;
			}
Example #20
0
		public virtual AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
		{
			for (int i = 0; i < node.Inputs.Length; i++)
				node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]);

			return node;
		}
Example #21
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			node.Left = VisitAlgebraNode(node.Left);
			node.Right = VisitAlgebraNode(node.Right);

			bool leftIsNull = node.Left is NullScanAlgebraNode;
			bool rightIsNull = node.Right is NullScanAlgebraNode;
			bool joinConditionAlwaysFalse = false;

			if (node.Predicate != null)
			{
				ExpressionNode predicate = node.Predicate;
				ConstantExpression predicateAsConstant = predicate as ConstantExpression;
				if (predicateAsConstant != null)
				{
					if (predicateAsConstant.AsBoolean)
						node.Predicate = null;
					else
						joinConditionAlwaysFalse = true;
				}
			}

			if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin || 
			    node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin || 
			    node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin)
			{
				node.SwapSides();
			}

			switch (node.Op)
			{
				case JoinAlgebraNode.JoinOperator.InnerJoin:
					if (joinConditionAlwaysFalse || leftIsNull || rightIsNull)
						return CreateNullScan(node.OutputList);
					break;
				case JoinAlgebraNode.JoinOperator.FullOuterJoin:
					if (leftIsNull && rightIsNull)
						return CreateNullScan(node.OutputList);
					if (leftIsNull)
						return PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.KeepExisting);
					if (rightIsNull)
						return PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting);
					if (joinConditionAlwaysFalse)
					{
						AlgebraNode left = PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.CreateNew);
						AlgebraNode right = PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.CreateNew);

						ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
						concatAlgebraNode.Inputs = new AlgebraNode[] { left, right };

						List<RowBufferEntry> outputList = new List<RowBufferEntry>();
						List<UnitedValueDefinition> definedValues = new List<UnitedValueDefinition>();
						for (int i = 0; i < node.Left.OutputList.Length; i++)
						{
							int leftIndex = i;
							int rightIndex = node.Right.OutputList.Length + i;

							UnitedValueDefinition definedValue = new UnitedValueDefinition();
							definedValue.Target = node.Left.OutputList[leftIndex];
							definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] };
							definedValues.Add(definedValue);
							outputList.Add(definedValue.Target);
						}
						for (int i = 0; i < node.Right.OutputList.Length; i++)
						{
							int leftIndex = node.Left.OutputList.Length + i;
							int rightIndex = i;

							UnitedValueDefinition definedValue = new UnitedValueDefinition();
							definedValue.Target = node.Right.OutputList[rightIndex];
							definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] };
							definedValues.Add(definedValue);
							outputList.Add(definedValue.Target);
						}

						concatAlgebraNode.DefinedValues = definedValues.ToArray();
						concatAlgebraNode.OutputList = outputList.ToArray();
						return concatAlgebraNode;
					}
					break;
				case JoinAlgebraNode.JoinOperator.LeftOuterJoin:
					if (leftIsNull)
						return CreateNullScan(node.OutputList);
					if (rightIsNull || joinConditionAlwaysFalse)
						return PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting);
					break;
				case JoinAlgebraNode.JoinOperator.LeftSemiJoin:
					if (leftIsNull || rightIsNull || joinConditionAlwaysFalse)
						return CreateNullScan(node.OutputList);
					if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right))
						return node.Left;
					break;
				case JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin:
					if (leftIsNull)
						return CreateNullScan(node.OutputList);
					if (rightIsNull || joinConditionAlwaysFalse)
						return node.Left;
					if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right))
						return CreateNullScan(node.OutputList);
					break;
			}
            
			return node;
		}
Example #22
0
		private static AlgebraNode AlgebrizeRecursiveCte(CommonTableBinding commonTableBinding)
		{
			// It is a recursive query.
			//
			// Create row buffer entry that is used to guard the recursion and the primary table spool
			// that spools the results needed by nested recursion calls.

			ExpressionBuilder expressionBuilder = new ExpressionBuilder();
			StackedTableSpoolAlgebraNode primaryTableSpool = new StackedTableSpoolAlgebraNode();

			RowBufferEntry anchorRecursionLevel;
			RowBufferEntry[] anchorOutput;
			AlgebraNode anchorNode;

			#region Anchor member
			{
				// Emit anchor member.

				AlgebraNode algebrizedAnchor = Convert(commonTableBinding.AnchorMember);

				// Emit compute scalar that initializes the recursion level to 0.

				anchorRecursionLevel = new RowBufferEntry(typeof(int));
				ComputedValueDefinition computedValueDefinition1 = new ComputedValueDefinition();
				computedValueDefinition1.Target = anchorRecursionLevel;
				computedValueDefinition1.Expression = LiteralExpression.FromInt32(0);

				ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
				computeScalarAlgebraNode.Input = algebrizedAnchor;
				computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { computedValueDefinition1 };

				anchorOutput = algebrizedAnchor.OutputList;
				anchorNode = computeScalarAlgebraNode;
			}
			#endregion

			RowBufferEntry incrementedRecursionLevel;
			RowBufferEntry[] tableSpoolOutput;
			AlgebraNode tableSpoolNode;

			#region Table spool
			{
				// Emit table spool reference.

				RowBufferEntry recursionLevelRefEntry = new RowBufferEntry(typeof(int));
				tableSpoolOutput = new RowBufferEntry[anchorOutput.Length];
				for (int i = 0; i < tableSpoolOutput.Length; i++)
					tableSpoolOutput[i] = new RowBufferEntry(anchorOutput[i].DataType);

				StackedTableSpoolRefAlgebraNode tableSpoolReference = new StackedTableSpoolRefAlgebraNode();
				tableSpoolReference.PrimarySpool = primaryTableSpool;
				tableSpoolReference.DefinedValues = ArrayHelpers.JoinArrays(new RowBufferEntry[] { recursionLevelRefEntry }, tableSpoolOutput);

				// Emit compute scalar that increases the recursion level by one and renames
				// columns from the spool to the CTE column buffer entries.

				expressionBuilder.Push(new RowBufferEntryExpression(recursionLevelRefEntry));
				expressionBuilder.Push(LiteralExpression.FromInt32(1));
				expressionBuilder.PushBinary(BinaryOperator.Add);

				incrementedRecursionLevel = new RowBufferEntry(typeof(int));
				ComputedValueDefinition incremenedRecLevelValueDefinition = new ComputedValueDefinition();
				incremenedRecLevelValueDefinition.Target = incrementedRecursionLevel;
				incremenedRecLevelValueDefinition.Expression = expressionBuilder.Pop();

				CteColumnMappingFinder cteColumnMappingFinder = new CteColumnMappingFinder(commonTableBinding, tableSpoolOutput);
				foreach (QueryNode recursiveMember in commonTableBinding.RecursiveMembers)
					cteColumnMappingFinder.Visit(recursiveMember);

				CteColumnMapping[] cteColumnMappings = cteColumnMappingFinder.GetMappings();

				List<ComputedValueDefinition> definedValues = new List<ComputedValueDefinition>();
				definedValues.Add(incremenedRecLevelValueDefinition);
				foreach (CteColumnMapping cteColumnMapping in cteColumnMappings)
				{
					ComputedValueDefinition definedValue = new ComputedValueDefinition();
					definedValue.Target = cteColumnMapping.VirtualBufferEntry;
					definedValue.Expression = new RowBufferEntryExpression(cteColumnMapping.SpoolBufferEntry);
					definedValues.Add(definedValue);
				}

				ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
				computeScalarAlgebraNode.Input = tableSpoolReference;
				computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();

				tableSpoolNode = computeScalarAlgebraNode;
			}
			#endregion

			RowBufferEntry[] recursiveOutput;
			AlgebraNode recursiveNode;

			#region Recursive member(s)
			{
				// Emit all recursive parts. The join conditions to the recursive part are replaced by simple filters
				// in the nested Convert() call.

				ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
				concatAlgebraNode.Inputs = new AlgebraNode[commonTableBinding.RecursiveMembers.Length];
				for (int i = 0; i < commonTableBinding.RecursiveMembers.Length; i++)
					concatAlgebraNode.Inputs[i] = Convert(commonTableBinding, commonTableBinding.RecursiveMembers[i]);

				concatAlgebraNode.DefinedValues = new UnitedValueDefinition[anchorOutput.Length];
				for (int i = 0; i < anchorOutput.Length; i++)
				{
					List<RowBufferEntry> dependencies = new List<RowBufferEntry>();
					foreach (ResultAlgebraNode algebrizedRecursivePart in concatAlgebraNode.Inputs)
						dependencies.Add(algebrizedRecursivePart.OutputList[i]);

					concatAlgebraNode.DefinedValues[i] = new UnitedValueDefinition();
					concatAlgebraNode.DefinedValues[i].Target = new RowBufferEntry(anchorOutput[i].DataType);
					concatAlgebraNode.DefinedValues[i].DependendEntries = dependencies.ToArray();
				}

				// Calculate the recursive output.

				recursiveOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length];
				for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++)
					recursiveOutput[i] = concatAlgebraNode.DefinedValues[i].Target;

				// Emit cross join

				JoinAlgebraNode crossJoinNode = new JoinAlgebraNode();
				crossJoinNode.Left = tableSpoolNode;
				crossJoinNode.Right = concatAlgebraNode;

				// Emit assert that ensures that the recursion level is <= 100.

				expressionBuilder.Push(new RowBufferEntryExpression(incrementedRecursionLevel));
				expressionBuilder.Push(LiteralExpression.FromInt32(100));
				expressionBuilder.PushBinary(BinaryOperator.Greater);

				CaseExpression caseExpression = new CaseExpression();
				caseExpression.WhenExpressions = new ExpressionNode[1];
				caseExpression.WhenExpressions[0] = expressionBuilder.Pop();
				caseExpression.ThenExpressions = new ExpressionNode[1];
				caseExpression.ThenExpressions[0] = LiteralExpression.FromInt32(0);

				AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode();
				assertAlgebraNode.Input = crossJoinNode;
				assertAlgebraNode.AssertionType = AssertionType.BelowRecursionLimit;
				assertAlgebraNode.Predicate = caseExpression;

				recursiveNode = assertAlgebraNode;
			}
			#endregion

			RowBufferEntry[] algebrizedOutput;
			AlgebraNode algebrizedCte;

			#region Combination
			{
				// Create concat node to combine anchor and recursive part.

				ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
				concatAlgebraNode.Inputs = new AlgebraNode[2];
				concatAlgebraNode.Inputs[0] = anchorNode;
				concatAlgebraNode.Inputs[1] = recursiveNode;

				concatAlgebraNode.DefinedValues = new UnitedValueDefinition[anchorOutput.Length + 1];
				concatAlgebraNode.DefinedValues[0] = new UnitedValueDefinition();
				concatAlgebraNode.DefinedValues[0].Target = new RowBufferEntry(anchorRecursionLevel.DataType);
				concatAlgebraNode.DefinedValues[0].DependendEntries = new RowBufferEntry[] { anchorRecursionLevel, incrementedRecursionLevel };

				for (int i = 0; i < anchorOutput.Length; i++)
				{
					concatAlgebraNode.DefinedValues[i + 1] = new UnitedValueDefinition();
					concatAlgebraNode.DefinedValues[i + 1].Target = new RowBufferEntry(anchorOutput[i].DataType);
					concatAlgebraNode.DefinedValues[i + 1].DependendEntries = new RowBufferEntry[] { anchorOutput[i], recursiveOutput[i] };
				}

				algebrizedOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length];
				for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++)
					algebrizedOutput[i] = concatAlgebraNode.DefinedValues[i].Target;

				// Assign the combination as the input to the primray spool

				primaryTableSpool.Input = concatAlgebraNode;

				// The primary spool represents the result of the "inlined" CTE.

				algebrizedCte = primaryTableSpool;
			}
			#endregion

			algebrizedCte.OutputList = algebrizedOutput;
			return algebrizedCte;
		}
Example #23
0
        public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
        {
            if (expression.Op != BinaryOperator.LogicalAnd &&
                expression.Op != BinaryOperator.LogicalOr)
                return base.VisitBinaryExpression(expression);

            if (expression.Op == BinaryOperator.LogicalAnd)
            {
                // AND

                expression.Left = VisitExpression(expression.Left);
                expression.Right = VisitExpression(expression.Right);

                return expression;
            }
            else
            {
                // OR

                AlgebraNode input = GetAndResetLastNode();
                _probingEnabledStack.Push(false);

                List<ExpressionNode> scalarOrParts = new List<ExpressionNode>();
                List<AlgebraNode> algebrizedOrParts = new List<AlgebraNode>();
                foreach (ExpressionNode orPart in AstUtil.SplitCondition(LogicalOperator.Or, expression))
                {
                    if (!AstUtil.ContainsSubselect(orPart))
                    {
                        scalarOrParts.Add(orPart);
                    }
                    else
                    {
                        ExpressionNode replacedOrPart = VisitExpression(orPart);
                        FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                        filterAlgebraNode.Input = GetAndResetLastNode();
                        filterAlgebraNode.Predicate = replacedOrPart;
                        algebrizedOrParts.Add(filterAlgebraNode);
                    }
                }

                if (scalarOrParts.Count > 0)
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.Or, scalarOrParts);
                    filterAlgebraNode.Input = CreateConstantScan();
                    algebrizedOrParts.Insert(0, filterAlgebraNode);
                }

                _probingEnabledStack.Pop();

                ConcatAlgebraNode concat = new ConcatAlgebraNode();
                concat.DefinedValues = new UnitedValueDefinition[0];
                concat.Inputs = algebrizedOrParts.ToArray();

                RowBufferEntry probeColumn = CreateProbeColumn();
                JoinAlgebraNode leftSemiJoinBetweenInputAndConcat = new JoinAlgebraNode();
                leftSemiJoinBetweenInputAndConcat.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin;
                leftSemiJoinBetweenInputAndConcat.PassthruPredicate = CurrentPassthruPredicate;
                leftSemiJoinBetweenInputAndConcat.ProbeBufferEntry = probeColumn;
                leftSemiJoinBetweenInputAndConcat.Left = input;
                leftSemiJoinBetweenInputAndConcat.Right = concat;
                SetLastAlgebraNode(leftSemiJoinBetweenInputAndConcat);
                return CreateProbeColumnRef(probeColumn);
            }
        }
Example #24
0
		public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
		{
			base.VisitConcatAlgebraNode(node);
            
			List<AlgebraNode> nonEmptyInputs = new List<AlgebraNode>();

			foreach (AlgebraNode input in node.Inputs)
			{
				if (input is NullScanAlgebraNode)
				{
					// removed by not adding to list.
				}
				else
				{
					nonEmptyInputs.Add(input);
				}
			}

			if (nonEmptyInputs.Count == 0)
				return CreateNullScan(node.OutputList);

			if (nonEmptyInputs.Count == 1)
			{
				int inputIndex = Array.IndexOf(node.Inputs, nonEmptyInputs[0]);

				List<ComputedValueDefinition> definedValues = new List<ComputedValueDefinition>();
				ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
				computeScalarAlgebraNode.Input = nonEmptyInputs[0];
				foreach (UnitedValueDefinition unitedValueDefinition in node.DefinedValues)
				{
					ComputedValueDefinition computedValueDefinition = new ComputedValueDefinition();
					computedValueDefinition.Target = unitedValueDefinition.Target;
					computedValueDefinition.Expression = new RowBufferEntryExpression(unitedValueDefinition.DependendEntries[inputIndex]);
					definedValues.Add(computedValueDefinition);
				}
				computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
				computeScalarAlgebraNode.OutputList = node.OutputList;
				return computeScalarAlgebraNode;
			}

			node.Inputs = nonEmptyInputs.ToArray();

			// Update dependend entries

			for (int i = 0; i < node.DefinedValues.Length; i++)
			{
				UnitedValueDefinition definition = node.DefinedValues[i];
				List<RowBufferEntry> dependendEntries = new List<RowBufferEntry>();

				foreach (RowBufferEntry dependendEntry in definition.DependendEntries)
				{
					bool entryInAnyInput = false;

					foreach (AlgebraNode input in node.Inputs)
					{
						if (ArrayHelpers.Contains(input.OutputList, dependendEntry))
						{
							entryInAnyInput = true;
							break;
						}
					}

					if (entryInAnyInput)
						dependendEntries.Add(dependendEntry);
				}

				definition.DependendEntries = dependendEntries.ToArray();
			}
			return node;
		}
Example #25
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            bool leftIsNull  = node.Left is NullScanAlgebraNode;
            bool rightIsNull = node.Right is NullScanAlgebraNode;
            bool joinConditionAlwaysFalse = false;

            if (node.Predicate != null)
            {
                ExpressionNode     predicate           = node.Predicate;
                ConstantExpression predicateAsConstant = predicate as ConstantExpression;
                if (predicateAsConstant != null)
                {
                    if (predicateAsConstant.AsBoolean)
                    {
                        node.Predicate = null;
                    }
                    else
                    {
                        joinConditionAlwaysFalse = true;
                    }
                }
            }

            if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin)
            {
                node.SwapSides();
            }

            switch (node.Op)
            {
            case JoinAlgebraNode.JoinOperator.InnerJoin:
                if (joinConditionAlwaysFalse || leftIsNull || rightIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                break;

            case JoinAlgebraNode.JoinOperator.FullOuterJoin:
                if (leftIsNull && rightIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (leftIsNull)
                {
                    return(PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.KeepExisting));
                }
                if (rightIsNull)
                {
                    return(PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting));
                }
                if (joinConditionAlwaysFalse)
                {
                    AlgebraNode left  = PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.CreateNew);
                    AlgebraNode right = PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.CreateNew);

                    ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
                    concatAlgebraNode.Inputs = new AlgebraNode[] { left, right };

                    List <RowBufferEntry>        outputList    = new List <RowBufferEntry>();
                    List <UnitedValueDefinition> definedValues = new List <UnitedValueDefinition>();
                    for (int i = 0; i < node.Left.OutputList.Length; i++)
                    {
                        int leftIndex  = i;
                        int rightIndex = node.Right.OutputList.Length + i;

                        UnitedValueDefinition definedValue = new UnitedValueDefinition();
                        definedValue.Target           = node.Left.OutputList[leftIndex];
                        definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] };
                        definedValues.Add(definedValue);
                        outputList.Add(definedValue.Target);
                    }
                    for (int i = 0; i < node.Right.OutputList.Length; i++)
                    {
                        int leftIndex  = node.Left.OutputList.Length + i;
                        int rightIndex = i;

                        UnitedValueDefinition definedValue = new UnitedValueDefinition();
                        definedValue.Target           = node.Right.OutputList[rightIndex];
                        definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] };
                        definedValues.Add(definedValue);
                        outputList.Add(definedValue.Target);
                    }

                    concatAlgebraNode.DefinedValues = definedValues.ToArray();
                    concatAlgebraNode.OutputList    = outputList.ToArray();
                    return(concatAlgebraNode);
                }
                break;

            case JoinAlgebraNode.JoinOperator.LeftOuterJoin:
                if (leftIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (rightIsNull || joinConditionAlwaysFalse)
                {
                    return(PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting));
                }
                break;

            case JoinAlgebraNode.JoinOperator.LeftSemiJoin:
                if (leftIsNull || rightIsNull || joinConditionAlwaysFalse)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right))
                {
                    return(node.Left);
                }
                break;

            case JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin:
                if (leftIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (rightIsNull || joinConditionAlwaysFalse)
                {
                    return(node.Left);
                }
                if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right))
                {
                    return(CreateNullScan(node.OutputList));
                }
                break;
            }

            return(node);
        }
Example #26
0
		public override QueryNode VisitBinaryQuery(BinaryQuery query)
		{
			switch (query.Op)
			{
				case BinaryQueryOperator.Intersect:
				case BinaryQueryOperator.Except:
				{
					ResultAlgebraNode left = ((ResultAlgebraNode)ConvertAstNode(query.Left));
					ResultAlgebraNode right = ((ResultAlgebraNode)ConvertAstNode(query.Right));

					// Create distinct sort

					SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
					sortAlgebraNode.Distinct = true;
					sortAlgebraNode.Input = left;
					sortAlgebraNode.SortEntries = left.OutputList;
					sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length);

					// Insert left (anti) semi join to (except) intersect left and right.

					ExpressionBuilder expressionBuilder = new ExpressionBuilder();
					for (int i = 0; i < left.OutputList.Length; i++)
					{
						RowBufferEntryExpression leftExpr = new RowBufferEntryExpression();
						leftExpr.RowBufferEntry = left.OutputList[i];

						RowBufferEntryExpression rightExpr = new RowBufferEntryExpression();
						rightExpr.RowBufferEntry = right.OutputList[i];

						expressionBuilder.Push(leftExpr);
						expressionBuilder.Push(rightExpr);
						expressionBuilder.PushBinary(BinaryOperator.Equal);
						expressionBuilder.Push(leftExpr);
						expressionBuilder.PushIsNull();
						expressionBuilder.Push(rightExpr);
						expressionBuilder.PushIsNull();
						expressionBuilder.PushBinary(BinaryOperator.LogicalAnd);
						expressionBuilder.PushBinary(BinaryOperator.LogicalOr);
					}
					expressionBuilder.PushNAry(LogicalOperator.And);
					ExpressionNode joinCondition = expressionBuilder.Pop();

					JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
					if (query.Op == BinaryQueryOperator.Intersect)
						joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin;
					else
						joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin;
					joinAlgebraNode.Left = sortAlgebraNode;
					joinAlgebraNode.Right = right;
					joinAlgebraNode.Predicate = joinCondition;
					SetLastAlgebraNode(joinAlgebraNode);

					ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode();
					resultAlgebraNode.Input = GetLastAlgebraNode();
					resultAlgebraNode.OutputList = left.OutputList;
					resultAlgebraNode.ColumnNames = left.ColumnNames;
					SetLastAlgebraNode(resultAlgebraNode);
					break;
				}

				case BinaryQueryOperator.Union:
				case BinaryQueryOperator.UnionAll:
				{
					// Build a flat list with all inputs.

					List<QueryNode> inputList = AstUtil.FlattenBinaryQuery(query);

					AlgebraNode[] inputs = new AlgebraNode[inputList.Count];
					for (int i = 0; i < inputs.Length; i++)
						inputs[i] = ConvertAstNode(inputList[i]);

					int outputColumnCount = inputs[0].OutputList.Length;

					UnitedValueDefinition[] definedValues = new UnitedValueDefinition[outputColumnCount];
					List<RowBufferEntry> definedValueEntries = new List<RowBufferEntry>();

					for (int i = 0; i < outputColumnCount; i++)
					{
						RowBufferEntry rowBufferEntry = new RowBufferEntry(inputs[0].OutputList[i].DataType);
						definedValueEntries.Add(rowBufferEntry);

						UnitedValueDefinition definedValue = new UnitedValueDefinition();
						definedValue.Target = rowBufferEntry;

						List<RowBufferEntry> dependencies = new List<RowBufferEntry>();
						foreach (ResultAlgebraNode node in inputs)
							dependencies.Add(node.OutputList[i]);
						definedValue.DependendEntries = dependencies.ToArray();

						definedValues[i] = definedValue;
					}

					ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
					concatAlgebraNode.Inputs = inputs;
					concatAlgebraNode.DefinedValues = definedValues;
					SetLastAlgebraNode(concatAlgebraNode);

					if (query.Op == BinaryQueryOperator.Union)
					{
						SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
						sortAlgebraNode.Distinct = true;
						sortAlgebraNode.Input = GetLastAlgebraNode();
						sortAlgebraNode.SortEntries = definedValueEntries.ToArray();
						sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length);
						SetLastAlgebraNode(sortAlgebraNode);
					}

					ResultAlgebraNode unionResultAlgebraNode = new ResultAlgebraNode();
					unionResultAlgebraNode.Input = GetLastAlgebraNode();
					unionResultAlgebraNode.ColumnNames = ((ResultAlgebraNode)inputs[0]).ColumnNames;
					unionResultAlgebraNode.OutputList = definedValueEntries.ToArray();
					SetLastAlgebraNode(unionResultAlgebraNode);

					break;
				}
			}

			return query;
		}
Example #27
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            base.VisitConcatAlgebraNode(node);

            List <AlgebraNode> nonEmptyInputs = new List <AlgebraNode>();

            foreach (AlgebraNode input in node.Inputs)
            {
                if (input is NullScanAlgebraNode)
                {
                    // removed by not adding to list.
                }
                else
                {
                    nonEmptyInputs.Add(input);
                }
            }

            if (nonEmptyInputs.Count == 0)
            {
                return(CreateNullScan(node.OutputList));
            }

            if (nonEmptyInputs.Count == 1)
            {
                int inputIndex = Array.IndexOf(node.Inputs, nonEmptyInputs[0]);

                List <ComputedValueDefinition> definedValues            = new List <ComputedValueDefinition>();
                ComputeScalarAlgebraNode       computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                computeScalarAlgebraNode.Input = nonEmptyInputs[0];
                foreach (UnitedValueDefinition unitedValueDefinition in node.DefinedValues)
                {
                    ComputedValueDefinition computedValueDefinition = new ComputedValueDefinition();
                    computedValueDefinition.Target     = unitedValueDefinition.Target;
                    computedValueDefinition.Expression = new RowBufferEntryExpression(unitedValueDefinition.DependendEntries[inputIndex]);
                    definedValues.Add(computedValueDefinition);
                }
                computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
                computeScalarAlgebraNode.OutputList    = node.OutputList;
                return(computeScalarAlgebraNode);
            }

            node.Inputs = nonEmptyInputs.ToArray();

            // Update dependend entries

            for (int i = 0; i < node.DefinedValues.Length; i++)
            {
                UnitedValueDefinition definition       = node.DefinedValues[i];
                List <RowBufferEntry> dependendEntries = new List <RowBufferEntry>();

                foreach (RowBufferEntry dependendEntry in definition.DependendEntries)
                {
                    bool entryInAnyInput = false;

                    foreach (AlgebraNode input in node.Inputs)
                    {
                        if (ArrayHelpers.Contains(input.OutputList, dependendEntry))
                        {
                            entryInAnyInput = true;
                            break;
                        }
                    }

                    if (entryInAnyInput)
                    {
                        dependendEntries.Add(dependendEntry);
                    }
                }

                definition.DependendEntries = dependendEntries.ToArray();
            }
            return(node);
        }
Example #28
0
        public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
        {
            if (expression.Op != BinaryOperator.LogicalAnd &&
                expression.Op != BinaryOperator.LogicalOr)
            {
                return(base.VisitBinaryExpression(expression));
            }

            if (expression.Op == BinaryOperator.LogicalAnd)
            {
                // AND

                expression.Left  = VisitExpression(expression.Left);
                expression.Right = VisitExpression(expression.Right);

                return(expression);
            }
            else
            {
                // OR

                AlgebraNode input = GetAndResetLastNode();
                _probingEnabledStack.Push(false);

                List <ExpressionNode> scalarOrParts     = new List <ExpressionNode>();
                List <AlgebraNode>    algebrizedOrParts = new List <AlgebraNode>();
                foreach (ExpressionNode orPart in AstUtil.SplitCondition(LogicalOperator.Or, expression))
                {
                    if (!AstUtil.ContainsSubselect(orPart))
                    {
                        scalarOrParts.Add(orPart);
                    }
                    else
                    {
                        ExpressionNode    replacedOrPart    = VisitExpression(orPart);
                        FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                        filterAlgebraNode.Input     = GetAndResetLastNode();
                        filterAlgebraNode.Predicate = replacedOrPart;
                        algebrizedOrParts.Add(filterAlgebraNode);
                    }
                }

                if (scalarOrParts.Count > 0)
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.Or, scalarOrParts);
                    filterAlgebraNode.Input     = CreateConstantScan();
                    algebrizedOrParts.Insert(0, filterAlgebraNode);
                }

                _probingEnabledStack.Pop();

                ConcatAlgebraNode concat = new ConcatAlgebraNode();
                concat.DefinedValues = new UnitedValueDefinition[0];
                concat.Inputs        = algebrizedOrParts.ToArray();

                RowBufferEntry  probeColumn = CreateProbeColumn();
                JoinAlgebraNode leftSemiJoinBetweenInputAndConcat = new JoinAlgebraNode();
                leftSemiJoinBetweenInputAndConcat.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin;
                leftSemiJoinBetweenInputAndConcat.PassthruPredicate = CurrentPassthruPredicate;
                leftSemiJoinBetweenInputAndConcat.ProbeBufferEntry  = probeColumn;
                leftSemiJoinBetweenInputAndConcat.Left  = input;
                leftSemiJoinBetweenInputAndConcat.Right = concat;
                SetLastAlgebraNode(leftSemiJoinBetweenInputAndConcat);
                return(CreateProbeColumnRef(probeColumn));
            }
        }
Example #29
0
        public override QueryNode VisitBinaryQuery(BinaryQuery query)
        {
            switch (query.Op)
            {
            case BinaryQueryOperator.Intersect:
            case BinaryQueryOperator.Except:
            {
                ResultAlgebraNode left  = ((ResultAlgebraNode)ConvertAstNode(query.Left));
                ResultAlgebraNode right = ((ResultAlgebraNode)ConvertAstNode(query.Right));

                // Create distinct sort

                SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
                sortAlgebraNode.Distinct    = true;
                sortAlgebraNode.Input       = left;
                sortAlgebraNode.SortEntries = left.OutputList;
                sortAlgebraNode.SortOrders  = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length);

                // Insert left (anti) semi join to (except) intersect left and right.

                ExpressionBuilder expressionBuilder = new ExpressionBuilder();
                for (int i = 0; i < left.OutputList.Length; i++)
                {
                    RowBufferEntryExpression leftExpr = new RowBufferEntryExpression();
                    leftExpr.RowBufferEntry = left.OutputList[i];

                    RowBufferEntryExpression rightExpr = new RowBufferEntryExpression();
                    rightExpr.RowBufferEntry = right.OutputList[i];

                    expressionBuilder.Push(leftExpr);
                    expressionBuilder.Push(rightExpr);
                    expressionBuilder.PushBinary(BinaryOperator.Equal);
                    expressionBuilder.Push(leftExpr);
                    expressionBuilder.PushIsNull();
                    expressionBuilder.Push(rightExpr);
                    expressionBuilder.PushIsNull();
                    expressionBuilder.PushBinary(BinaryOperator.LogicalAnd);
                    expressionBuilder.PushBinary(BinaryOperator.LogicalOr);
                }
                expressionBuilder.PushNAry(LogicalOperator.And);
                ExpressionNode joinCondition = expressionBuilder.Pop();

                JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                if (query.Op == BinaryQueryOperator.Intersect)
                {
                    joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin;
                }
                else
                {
                    joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin;
                }
                joinAlgebraNode.Left      = sortAlgebraNode;
                joinAlgebraNode.Right     = right;
                joinAlgebraNode.Predicate = joinCondition;
                SetLastAlgebraNode(joinAlgebraNode);

                ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode();
                resultAlgebraNode.Input       = GetLastAlgebraNode();
                resultAlgebraNode.OutputList  = left.OutputList;
                resultAlgebraNode.ColumnNames = left.ColumnNames;
                SetLastAlgebraNode(resultAlgebraNode);
                break;
            }

            case BinaryQueryOperator.Union:
            case BinaryQueryOperator.UnionAll:
            {
                // Build a flat list with all inputs.

                List <QueryNode> inputList = AstUtil.FlattenBinaryQuery(query);

                AlgebraNode[] inputs = new AlgebraNode[inputList.Count];
                for (int i = 0; i < inputs.Length; i++)
                {
                    inputs[i] = ConvertAstNode(inputList[i]);
                }

                int outputColumnCount = inputs[0].OutputList.Length;

                UnitedValueDefinition[] definedValues       = new UnitedValueDefinition[outputColumnCount];
                List <RowBufferEntry>   definedValueEntries = new List <RowBufferEntry>();

                for (int i = 0; i < outputColumnCount; i++)
                {
                    RowBufferEntry rowBufferEntry = new RowBufferEntry(inputs[0].OutputList[i].DataType);
                    definedValueEntries.Add(rowBufferEntry);

                    UnitedValueDefinition definedValue = new UnitedValueDefinition();
                    definedValue.Target = rowBufferEntry;

                    List <RowBufferEntry> dependencies = new List <RowBufferEntry>();
                    foreach (ResultAlgebraNode node in inputs)
                    {
                        dependencies.Add(node.OutputList[i]);
                    }
                    definedValue.DependendEntries = dependencies.ToArray();

                    definedValues[i] = definedValue;
                }

                ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
                concatAlgebraNode.Inputs        = inputs;
                concatAlgebraNode.DefinedValues = definedValues;
                SetLastAlgebraNode(concatAlgebraNode);

                if (query.Op == BinaryQueryOperator.Union)
                {
                    SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
                    sortAlgebraNode.Distinct    = true;
                    sortAlgebraNode.Input       = GetLastAlgebraNode();
                    sortAlgebraNode.SortEntries = definedValueEntries.ToArray();
                    sortAlgebraNode.SortOrders  = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length);
                    SetLastAlgebraNode(sortAlgebraNode);
                }

                ResultAlgebraNode unionResultAlgebraNode = new ResultAlgebraNode();
                unionResultAlgebraNode.Input       = GetLastAlgebraNode();
                unionResultAlgebraNode.ColumnNames = ((ResultAlgebraNode)inputs[0]).ColumnNames;
                unionResultAlgebraNode.OutputList  = definedValueEntries.ToArray();
                SetLastAlgebraNode(unionResultAlgebraNode);

                break;
            }
            }

            return(query);
        }
Example #30
0
        private static AlgebraNode AlgebrizeRecursiveCte(CommonTableBinding commonTableBinding)
        {
            // It is a recursive query.
            //
            // Create row buffer entry that is used to guard the recursion and the primary table spool
            // that spools the results needed by nested recursion calls.

            ExpressionBuilder            expressionBuilder = new ExpressionBuilder();
            StackedTableSpoolAlgebraNode primaryTableSpool = new StackedTableSpoolAlgebraNode();

            RowBufferEntry anchorRecursionLevel;

            RowBufferEntry[] anchorOutput;
            AlgebraNode      anchorNode;

            #region Anchor member
            {
                // Emit anchor member.

                AlgebraNode algebrizedAnchor = Convert(commonTableBinding.AnchorMember);

                // Emit compute scalar that initializes the recursion level to 0.

                anchorRecursionLevel = new RowBufferEntry(typeof(int));
                ComputedValueDefinition computedValueDefinition1 = new ComputedValueDefinition();
                computedValueDefinition1.Target     = anchorRecursionLevel;
                computedValueDefinition1.Expression = LiteralExpression.FromInt32(0);

                ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                computeScalarAlgebraNode.Input         = algebrizedAnchor;
                computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { computedValueDefinition1 };

                anchorOutput = algebrizedAnchor.OutputList;
                anchorNode   = computeScalarAlgebraNode;
            }
            #endregion

            RowBufferEntry   incrementedRecursionLevel;
            RowBufferEntry[] tableSpoolOutput;
            AlgebraNode      tableSpoolNode;

            #region Table spool
            {
                // Emit table spool reference.

                RowBufferEntry recursionLevelRefEntry = new RowBufferEntry(typeof(int));
                tableSpoolOutput = new RowBufferEntry[anchorOutput.Length];
                for (int i = 0; i < tableSpoolOutput.Length; i++)
                {
                    tableSpoolOutput[i] = new RowBufferEntry(anchorOutput[i].DataType);
                }

                StackedTableSpoolRefAlgebraNode tableSpoolReference = new StackedTableSpoolRefAlgebraNode();
                tableSpoolReference.PrimarySpool  = primaryTableSpool;
                tableSpoolReference.DefinedValues = ArrayHelpers.JoinArrays(new RowBufferEntry[] { recursionLevelRefEntry }, tableSpoolOutput);

                // Emit compute scalar that increases the recursion level by one and renames
                // columns from the spool to the CTE column buffer entries.

                expressionBuilder.Push(new RowBufferEntryExpression(recursionLevelRefEntry));
                expressionBuilder.Push(LiteralExpression.FromInt32(1));
                expressionBuilder.PushBinary(BinaryOperator.Add);

                incrementedRecursionLevel = new RowBufferEntry(typeof(int));
                ComputedValueDefinition incremenedRecLevelValueDefinition = new ComputedValueDefinition();
                incremenedRecLevelValueDefinition.Target     = incrementedRecursionLevel;
                incremenedRecLevelValueDefinition.Expression = expressionBuilder.Pop();

                CteColumnMappingFinder cteColumnMappingFinder = new CteColumnMappingFinder(commonTableBinding, tableSpoolOutput);
                foreach (QueryNode recursiveMember in commonTableBinding.RecursiveMembers)
                {
                    cteColumnMappingFinder.Visit(recursiveMember);
                }

                CteColumnMapping[] cteColumnMappings = cteColumnMappingFinder.GetMappings();

                List <ComputedValueDefinition> definedValues = new List <ComputedValueDefinition>();
                definedValues.Add(incremenedRecLevelValueDefinition);
                foreach (CteColumnMapping cteColumnMapping in cteColumnMappings)
                {
                    ComputedValueDefinition definedValue = new ComputedValueDefinition();
                    definedValue.Target     = cteColumnMapping.VirtualBufferEntry;
                    definedValue.Expression = new RowBufferEntryExpression(cteColumnMapping.SpoolBufferEntry);
                    definedValues.Add(definedValue);
                }

                ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                computeScalarAlgebraNode.Input         = tableSpoolReference;
                computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();

                tableSpoolNode = computeScalarAlgebraNode;
            }
            #endregion

            RowBufferEntry[] recursiveOutput;
            AlgebraNode      recursiveNode;

            #region Recursive member(s)
            {
                // Emit all recursive parts. The join conditions to the recursive part are replaced by simple filters
                // in the nested Convert() call.

                ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
                concatAlgebraNode.Inputs = new AlgebraNode[commonTableBinding.RecursiveMembers.Length];
                for (int i = 0; i < commonTableBinding.RecursiveMembers.Length; i++)
                {
                    concatAlgebraNode.Inputs[i] = Convert(commonTableBinding, commonTableBinding.RecursiveMembers[i]);
                }

                concatAlgebraNode.DefinedValues = new UnitedValueDefinition[anchorOutput.Length];
                for (int i = 0; i < anchorOutput.Length; i++)
                {
                    List <RowBufferEntry> dependencies = new List <RowBufferEntry>();
                    foreach (ResultAlgebraNode algebrizedRecursivePart in concatAlgebraNode.Inputs)
                    {
                        dependencies.Add(algebrizedRecursivePart.OutputList[i]);
                    }

                    concatAlgebraNode.DefinedValues[i]                  = new UnitedValueDefinition();
                    concatAlgebraNode.DefinedValues[i].Target           = new RowBufferEntry(anchorOutput[i].DataType);
                    concatAlgebraNode.DefinedValues[i].DependendEntries = dependencies.ToArray();
                }

                // Calculate the recursive output.

                recursiveOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length];
                for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++)
                {
                    recursiveOutput[i] = concatAlgebraNode.DefinedValues[i].Target;
                }

                // Emit cross join

                JoinAlgebraNode crossJoinNode = new JoinAlgebraNode();
                crossJoinNode.Left  = tableSpoolNode;
                crossJoinNode.Right = concatAlgebraNode;

                // Emit assert that ensures that the recursion level is <= 100.

                expressionBuilder.Push(new RowBufferEntryExpression(incrementedRecursionLevel));
                expressionBuilder.Push(LiteralExpression.FromInt32(100));
                expressionBuilder.PushBinary(BinaryOperator.Greater);

                CaseExpression caseExpression = new CaseExpression();
                caseExpression.WhenExpressions    = new ExpressionNode[1];
                caseExpression.WhenExpressions[0] = expressionBuilder.Pop();
                caseExpression.ThenExpressions    = new ExpressionNode[1];
                caseExpression.ThenExpressions[0] = LiteralExpression.FromInt32(0);

                AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode();
                assertAlgebraNode.Input         = crossJoinNode;
                assertAlgebraNode.AssertionType = AssertionType.BelowRecursionLimit;
                assertAlgebraNode.Predicate     = caseExpression;

                recursiveNode = assertAlgebraNode;
            }
            #endregion

            RowBufferEntry[] algebrizedOutput;
            AlgebraNode      algebrizedCte;

            #region Combination
            {
                // Create concat node to combine anchor and recursive part.

                ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
                concatAlgebraNode.Inputs    = new AlgebraNode[2];
                concatAlgebraNode.Inputs[0] = anchorNode;
                concatAlgebraNode.Inputs[1] = recursiveNode;

                concatAlgebraNode.DefinedValues                     = new UnitedValueDefinition[anchorOutput.Length + 1];
                concatAlgebraNode.DefinedValues[0]                  = new UnitedValueDefinition();
                concatAlgebraNode.DefinedValues[0].Target           = new RowBufferEntry(anchorRecursionLevel.DataType);
                concatAlgebraNode.DefinedValues[0].DependendEntries = new RowBufferEntry[] { anchorRecursionLevel, incrementedRecursionLevel };

                for (int i = 0; i < anchorOutput.Length; i++)
                {
                    concatAlgebraNode.DefinedValues[i + 1]                  = new UnitedValueDefinition();
                    concatAlgebraNode.DefinedValues[i + 1].Target           = new RowBufferEntry(anchorOutput[i].DataType);
                    concatAlgebraNode.DefinedValues[i + 1].DependendEntries = new RowBufferEntry[] { anchorOutput[i], recursiveOutput[i] };
                }

                algebrizedOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length];
                for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++)
                {
                    algebrizedOutput[i] = concatAlgebraNode.DefinedValues[i].Target;
                }

                // Assign the combination as the input to the primray spool

                primaryTableSpool.Input = concatAlgebraNode;

                // The primary spool represents the result of the "inlined" CTE.

                algebrizedCte = primaryTableSpool;
            }
            #endregion

            algebrizedCte.OutputList = algebrizedOutput;
            return(algebrizedCte);
        }
Example #31
0
		public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
		{
			_xmlWriter.WriteStartElement("concatAlgebraNode");

			for (int i = 0; i < node.Inputs.Length; i++)
				Visit(node.Inputs[i]);

			_xmlWriter.WriteEndElement();

			return node;
		}
Example #32
0
		public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
		{
			ConcatenationIterator concatenationIterator = new ConcatenationIterator();
			concatenationIterator.RowBuffer = new object[node.OutputList.Length];
			concatenationIterator.Inputs = new Iterator[node.Inputs.Length];
			concatenationIterator.InputOutput = new IteratorOutput[node.Inputs.Length][];
			for (int i = 0; i < concatenationIterator.Inputs.Length; i++)
			{
				concatenationIterator.Inputs[i] = ConvertAlgebraNode(node.Inputs[i]);

				List<IteratorOutput> inputOutputList = new List<IteratorOutput>();
				foreach (UnitedValueDefinition unitedValueDefinition in node.DefinedValues)
				{
					IteratorOutput iteratorOutput = new IteratorOutput();
					iteratorOutput.SourceIndex = Array.IndexOf(node.Inputs[i].OutputList, unitedValueDefinition.DependendEntries[i]);
					iteratorOutput.TargetIndex = Array.IndexOf(node.OutputList, unitedValueDefinition.Target);
					inputOutputList.Add(iteratorOutput);
				}
				concatenationIterator.InputOutput[i] = inputOutputList.ToArray();
			}
			SetLastIterator(node, concatenationIterator);

			return node;
		}
Example #33
0
        public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node)
        {
            List<ShowPlanElement> inputList = new List<ShowPlanElement>();

            foreach (AlgebraNode inputNode in node.Inputs)
                inputList.Add(ConvertNode(inputNode));

            PropertyListBuilder propertyListBuilder = new PropertyListBuilder();
            AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOutputList, node.OutputList);
            AddStatistics(propertyListBuilder, node.StatisticsIterator);
            AddDefinedValues(propertyListBuilder, node.DefinedValues);

            IList<ShowPlanProperty> properties = propertyListBuilder.ToList();

            ShowPlanElement element = new ShowPlanElement(ShowPlanOperator.Concatenation, properties, inputList.ToArray());
            _currentElement = element;

            return node;
        }