Example #1
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // For easier handling we replace right operations by equivalent
            // left operations.

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

            // Visit children

            bool semiJoinContext;

            semiJoinContext = (node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin ||
                               node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin);
            _semiJoinContextFlagStack.Push(semiJoinContext);
            node.Left = VisitAlgebraNode(node.Left);
            _semiJoinContextFlagStack.Pop();

            semiJoinContext = (node.Op == JoinAlgebraNode.JoinOperator.LeftSemiJoin ||
                               node.Op == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin);
            _semiJoinContextFlagStack.Push(semiJoinContext);
            node.Right = VisitAlgebraNode(node.Right);
            _semiJoinContextFlagStack.Pop();

            return node;
        }
Example #2
0
        private static AlgebraNode PadLeftWithNullsOnRightSide(JoinAlgebraNode node, RowBufferCreationMode rowBufferCreationMode)
        {
            ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();

            computeScalarAlgebraNode.Input = node.Left;

            List <RowBufferEntry> outputList = new List <RowBufferEntry>();

            outputList.AddRange(node.Left.OutputList);

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

            foreach (RowBufferEntry rowBufferEntry in node.Right.OutputList)
            {
                ComputedValueDefinition definedValue = new ComputedValueDefinition();

                if (rowBufferCreationMode == RowBufferCreationMode.KeepExisting)
                {
                    definedValue.Target = rowBufferEntry;
                }
                else
                {
                    definedValue.Target = new RowBufferEntry(rowBufferEntry.DataType);
                }

                definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType);
                definedValues.Add(definedValue);
                outputList.Add(definedValue.Target);
            }

            computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
            computeScalarAlgebraNode.OutputList    = outputList.ToArray();

            return(computeScalarAlgebraNode);
        }
Example #3
0
        private AlgebraNode PushOverJoin(ComputeScalarAlgebraNode node)
        {
            JoinAlgebraNode joinAlgebraNode = (JoinAlgebraNode)node.Input;

            RowBufferEntry[] leftDefinedValues  = AstUtil.GetDefinedValueEntries(joinAlgebraNode.Left);
            RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(joinAlgebraNode.Right);

            List <ComputedValueDefinition> remainingValueDefinitions   = new List <ComputedValueDefinition>();
            List <ComputedValueDefinition> leftPushedValueDefinitions  = new List <ComputedValueDefinition>();
            List <ComputedValueDefinition> rightPushedValueDefinitions = new List <ComputedValueDefinition>();

            bool canPushToLeftSide = joinAlgebraNode.Op != JoinAlgebraNode.JoinOperator.RightOuterJoin &&
                                     joinAlgebraNode.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin;

            bool canPushToRightSide = joinAlgebraNode.Op != JoinAlgebraNode.JoinOperator.LeftOuterJoin &&
                                      joinAlgebraNode.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin;

            foreach (ComputedValueDefinition valueDefinition in node.DefinedValues)
            {
                RowBufferEntry[] referencedValues      = AstUtil.GetRowBufferEntryReferences(valueDefinition.Expression);
                bool             referencesProbeColumn = ArrayHelpers.Contains(referencedValues, joinAlgebraNode.ProbeBufferEntry);

                if (!referencesProbeColumn && canPushToLeftSide && AstUtil.DoesNotReference(referencedValues, rightDefinedValues))
                {
                    leftPushedValueDefinitions.Add(valueDefinition);
                }
                else if (!referencesProbeColumn && canPushToRightSide && AstUtil.DoesNotReference(referencedValues, leftDefinedValues))
                {
                    rightPushedValueDefinitions.Add(valueDefinition);
                }
                else
                {
                    remainingValueDefinitions.Add(valueDefinition);
                }
            }

            if (leftPushedValueDefinitions.Count > 0)
            {
                ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                computeScalarAlgebraNode.DefinedValues = leftPushedValueDefinitions.ToArray();
                computeScalarAlgebraNode.Input         = joinAlgebraNode.Left;
                joinAlgebraNode.Left = VisitAlgebraNode(computeScalarAlgebraNode);
            }

            if (rightPushedValueDefinitions.Count > 0)
            {
                ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                computeScalarAlgebraNode.DefinedValues = rightPushedValueDefinitions.ToArray();
                computeScalarAlgebraNode.Input         = joinAlgebraNode.Right;
                joinAlgebraNode.Right = VisitAlgebraNode(computeScalarAlgebraNode);
            }

            if (remainingValueDefinitions.Count == 0)
            {
                return(joinAlgebraNode);
            }

            node.DefinedValues = remainingValueDefinitions.ToArray();
            return(node);
        }
Example #4
0
		private static AlgebraNode PadLeftWithNullsOnRightSide(JoinAlgebraNode node, RowBufferCreationMode rowBufferCreationMode)
		{
			ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
			computeScalarAlgebraNode.Input = node.Left;

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

			List<ComputedValueDefinition> definedValues = new List<ComputedValueDefinition>();
			foreach (RowBufferEntry rowBufferEntry in node.Right.OutputList)
			{
				ComputedValueDefinition definedValue = new ComputedValueDefinition();

				if (rowBufferCreationMode == RowBufferCreationMode.KeepExisting)
				{
					definedValue.Target = rowBufferEntry;
				}
				else
				{
					definedValue.Target = new RowBufferEntry(rowBufferEntry.DataType);
				}

				definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType);
				definedValues.Add(definedValue);
				outputList.Add(definedValue.Target);
			}

			computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
			computeScalarAlgebraNode.OutputList = outputList.ToArray();

			return computeScalarAlgebraNode;
		}
Example #5
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 #6
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			// Reorder
			//
			// A LSJ (B LOJ C)      --->    (A LOJ C) LSJ B     (LOJ has no join condition and C produces at most one row)

			if (node.Op == JoinAlgebraNode.JoinOperator.LeftSemiJoin ||
			    node.Op == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin)
			{
				JoinAlgebraNode rightChildJoin = node.Right as JoinAlgebraNode;
                
				if (rightChildJoin != null && 
				    rightChildJoin.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin &&
				    rightChildJoin.Predicate == null &&
				    AstUtil.WillProduceAtMostOneRow(rightChildJoin.Right))
				{
					node.Right = rightChildJoin.Left;
					rightChildJoin.Left = node.Left;
					node.Left = rightChildJoin;
					return VisitAlgebraNode(node);
				}
			}

			node.Left = VisitAlgebraNode(node.Left);
			node.Right = VisitAlgebraNode(node.Right);
			return node;
		}
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // For easier handling we replace right operations by equivalent
            // left operations.

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

            // Visit children

            bool semiJoinContext;

            semiJoinContext = (node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin ||
                               node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin);
            _semiJoinContextFlagStack.Push(semiJoinContext);
            node.Left = VisitAlgebraNode(node.Left);
            _semiJoinContextFlagStack.Pop();

            semiJoinContext = (node.Op == JoinAlgebraNode.JoinOperator.LeftSemiJoin ||
                               node.Op == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin);
            _semiJoinContextFlagStack.Push(semiJoinContext);
            node.Right = VisitAlgebraNode(node.Right);
            _semiJoinContextFlagStack.Pop();

            return(node);
        }
        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);
        }
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // Reorder
            //
            // A LSJ (B LOJ C)      --->    (A LOJ C) LSJ B     (LOJ has no join condition and C produces at most one row)

            if (node.Op == JoinAlgebraNode.JoinOperator.LeftSemiJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin)
            {
                JoinAlgebraNode rightChildJoin = node.Right as JoinAlgebraNode;

                if (rightChildJoin != null &&
                    rightChildJoin.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin &&
                    rightChildJoin.Predicate == null &&
                    AstUtil.WillProduceAtMostOneRow(rightChildJoin.Right))
                {
                    node.Right          = rightChildJoin.Left;
                    rightChildJoin.Left = node.Left;
                    node.Left           = rightChildJoin;
                    return(VisitAlgebraNode(node));
                }
            }

            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);
            return(node);
        }
Example #10
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            Visit(node.Left);
            Visit(node.Right);
            _definedValueEntries.Add(node.ProbeBufferEntry);

            return(node);
        }
Example #11
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			Visit(node.Left);
			Visit(node.Right);
			_definedValueEntries.Add(node.ProbeBufferEntry);

			return node;
		}
Example #12
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			Visit(node.Left);
			Visit(node.Right);

			node.OuterReferences = AstUtil.GetOuterReferences(node);
            
			return node;
		}
Example #13
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            Visit(node.Left);
            Visit(node.Right);

            node.OuterReferences = AstUtil.GetOuterReferences(node);

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

            if (node.ProbeBufferEntry != null)
                NameEntry(node.ProbeBufferEntry, EXPRESSION_NAME_FMT_STR);

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

            if (node.ProbeBufferEntry != null)
            {
                NameEntry(node.ProbeBufferEntry, EXPRESSION_NAME_FMT_STR);
            }

            return(node);
        }
Example #16
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // Get declared tables of left and right

            RowBufferEntry[] leftDefinedValues = AstUtil.GetDefinedValueEntries(node.Left);
            RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(node.Right);

            // Analyze AND-parts of Condition

            if (node.Predicate != null)
            {
                List<ExpressionNode> leftAndParts = new List<ExpressionNode>();
                List<ExpressionNode> rightAndParts = new List<ExpressionNode>();
                List<ExpressionNode> remainingAndParts = new List<ExpressionNode>();

                foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, node.Predicate))
                {
                    // Check if we can push this AND-part down.

                    if (AstUtil.AllowsLeftPushDown(node.Op) && AstUtil.ExpressionDoesNotReference(andPart, rightDefinedValues))
                    {
                        leftAndParts.Add(andPart);
                    }
                    else if (AstUtil.AllowsRightPushDown(node.Op) && AstUtil.ExpressionDoesNotReference(andPart, leftDefinedValues))
                    {
                        rightAndParts.Add(andPart);
                    }
                    else
                    {
                        remainingAndParts.Add(andPart);
                    }
                }

                if (leftAndParts.Count > 0)
                {
                    node.Left = GetFilterFromAndParts(leftAndParts, node.Left);
                }

                if (rightAndParts.Count > 0)
                {
                    node.Right = GetFilterFromAndParts(rightAndParts, node.Right);
                }

                node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);
            }

            // Visit children

            node.Left = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            return node;
        }
Example #17
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // Get declared tables of left and right

            RowBufferEntry[] leftDefinedValues  = AstUtil.GetDefinedValueEntries(node.Left);
            RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(node.Right);

            // Analyze AND-parts of Condition

            if (node.Predicate != null)
            {
                List <ExpressionNode> leftAndParts      = new List <ExpressionNode>();
                List <ExpressionNode> rightAndParts     = new List <ExpressionNode>();
                List <ExpressionNode> remainingAndParts = new List <ExpressionNode>();

                foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, node.Predicate))
                {
                    // Check if we can push this AND-part down.

                    if (AstUtil.AllowsLeftPushDown(node.Op) && AstUtil.ExpressionDoesNotReference(andPart, rightDefinedValues))
                    {
                        leftAndParts.Add(andPart);
                    }
                    else if (AstUtil.AllowsRightPushDown(node.Op) && AstUtil.ExpressionDoesNotReference(andPart, leftDefinedValues))
                    {
                        rightAndParts.Add(andPart);
                    }
                    else
                    {
                        remainingAndParts.Add(andPart);
                    }
                }

                if (leftAndParts.Count > 0)
                {
                    node.Left = GetFilterFromAndParts(leftAndParts, node.Left);
                }

                if (rightAndParts.Count > 0)
                {
                    node.Right = GetFilterFromAndParts(rightAndParts, node.Right);
                }

                node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);
            }

            // Visit children

            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            return(node);
        }
Example #18
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            ShowPlanElement leftElement  = ConvertNode(node.Left);
            ShowPlanElement rightElement = ConvertNode(node.Right);

            PropertyListBuilder propertyListBuilder = new PropertyListBuilder();

            AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOutputList, node.OutputList);
            propertyListBuilder.Write(Resources.ShowPlanKeyLogicalOperator, LogicalOperatorToString(node.Op));
            AddStatistics(propertyListBuilder, node.StatisticsIterator);

            if (node.Predicate != null)
            {
                propertyListBuilder.Write(Resources.ShowPlanKeyPredicate, node.Predicate.GenerateSource());
            }

            if (node.OuterReferences != null && node.OuterReferences.Length > 0)
            {
                AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOuterReferences, node.OuterReferences);
            }

            if (node.ProbeBufferEntry != null)
            {
                WriteRowBufferEntry(propertyListBuilder, Resources.ShowPlanKeyProbeColumn, node.ProbeBufferEntry);
            }

            if (node.PassthruPredicate != null)
            {
                propertyListBuilder.Write(Resources.ShowPlanKeyPassthru, node.PassthruPredicate.GenerateSource());
            }

            // We give a warning if a join has no predicate and no outer reference.
            // In this case the join would simply multiply the other side.
            // However, we supppress the warning if any side is known at produce at
            // most one row.
            if (node.Predicate == null &&
                (node.OuterReferences == null || node.OuterReferences.Length == 0) &&
                !AstUtil.WillProduceAtMostOneRow(node.Left) &&
                !AstUtil.WillProduceAtMostOneRow(node.Right))
            {
                propertyListBuilder.Write(Resources.ShowPlanKeyWarning, Resources.ShowPlanWarningNoJoinPredicate);
            }

            IList <ShowPlanProperty> properties = propertyListBuilder.ToList();
            ShowPlanElement          element    = new ShowPlanElement(ShowPlanOperator.NestedLoops, properties, leftElement, rightElement);

            _currentElement = element;

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

            RowBufferEntry[] outerReferences = AstUtil.GetOuterReferences(node);
            if (outerReferences != null && outerReferences.Length > 0)
                _outerReferences.Push(node.OuterReferences);

            node.Right = VisitAlgebraNode(node.Right);

            if (outerReferences != null && outerReferences.Length > 0)
                _outerReferences.Pop();

            return node;
        }
Example #20
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            _xmlWriter.WriteStartElement("joinAlgebraNode");
            _xmlWriter.WriteAttributeString("op", node.Op.ToString());

            WriteRowBufferEntries("externalColumnDependencies", node.OuterReferences);
            WriteAstNode("leftNode", node.Left);
            WriteAstNode("rightNode", node.Right);

            WriteAstNode("joinCondition", node.Predicate);

            _xmlWriter.WriteEndElement();

            return(node);
        }
Example #21
0
		private static bool SemiJoinDoesNotDependOn(JoinAlgebraNode.JoinOperator op, ExpressionNode part, RowBufferEntry[] leftDefinedValues, RowBufferEntry[] rightDefinedValues)
		{
			if (op == JoinAlgebraNode.JoinOperator.LeftSemiJoin ||
				op == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin)
			{
				return AstUtil.ExpressionDoesNotReference(part, rightDefinedValues);
			}

			if (op == JoinAlgebraNode.JoinOperator.RightSemiJoin ||
				op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin)
			{
				return AstUtil.ExpressionDoesNotReference(part, leftDefinedValues);
			}

			return true;
		}
Example #22
0
        public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements)
        {
            JoinAlgebraNode result = new JoinAlgebraNode();

            result.StatisticsIterator = StatisticsIterator;
            result.OutputList         = ArrayHelpers.Clone(OutputList);
            result.Left  = (AlgebraNode)_left.Clone(alreadyClonedElements);
            result.Right = (AlgebraNode)_right.Clone(alreadyClonedElements);
            result.Op    = _op;
            if (_predicate != null)
            {
                result.Predicate = (ExpressionNode)_predicate.Clone(alreadyClonedElements);
            }
            result.OuterReferences = ArrayHelpers.Clone(_outerReferences);
            return(result);
        }
Example #23
0
        public override ExpressionNode VisitSingleRowSubselect(SingleRowSubselect expression)
        {
            AlgebraNode       inputNode          = GetOrCreateInput();
            ResultAlgebraNode algebrizedSubquery = Algebrizer.Convert(expression.Query);
            ResultAlgebraNode assertedSubquery   = CreateAssertedSubquery(algebrizedSubquery);

            JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();

            joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
            joinAlgebraNode.Op    = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
            joinAlgebraNode.Left  = inputNode;
            joinAlgebraNode.Right = assertedSubquery;
            SetLastAlgebraNode(joinAlgebraNode);

            return(new RowBufferEntryExpression(assertedSubquery.OutputList[0]));
        }
Example #24
0
        public static RowBufferEntry[] GetOuterReferences(JoinAlgebraNode node)
        {
            RowBufferEntry[] leftDefinedValues = GetDefinedValueEntries(node.Left);

            RowBufferEntry[]      rowBufferEntries   = GetRowBufferEntryReferences(node.Right);
            List <RowBufferEntry> outerReferenceList = new List <RowBufferEntry>();

            foreach (RowBufferEntry rightColumnDependency in rowBufferEntries)
            {
                if (ArrayHelpers.Contains(leftDefinedValues, rightColumnDependency))
                {
                    outerReferenceList.Add(rightColumnDependency);
                }
            }

            return(outerReferenceList.ToArray());
        }
Example #25
0
        public virtual AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            if (node.Predicate != null)
            {
                node.Predicate = VisitExpression(node.Predicate);
            }

            if (node.PassthruPredicate != null)
            {
                node.PassthruPredicate = VisitExpression(node.PassthruPredicate);
            }

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

            List <RowBufferEntry> outputList = new List <RowBufferEntry>();

            outputList.AddRange(node.Left.OutputList);
            outputList.AddRange(node.Right.OutputList);
            if (node.ProbeBufferEntry != null)
            {
                outputList.Add(node.ProbeBufferEntry);
            }
            node.OutputList = outputList.ToArray();

            return(node);
        }
Example #27
0
        public override ExpressionNode VisitExistsSubselect(ExistsSubselect expression)
        {
            AlgebraNode       input           = GetAndResetLastNode();
            ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query);

            if (!expression.Negated && AstUtil.WillProduceAtLeastOneRow(algebrizedQuery))
            {
                if (input == null)
                {
                    SetLastAlgebraNode(CreateConstantScan());
                }
                else
                {
                    SetLastAlgebraNode(input);
                }

                return(LiteralExpression.FromBoolean(true));
            }


            if (!expression.Negated && !ProbingEnabled && input == null)
            {
                SetLastAlgebraNode(algebrizedQuery);
                return(LiteralExpression.FromBoolean(true));
            }
            else
            {
                if (input == null)
                {
                    input = CreateConstantScan();
                }

                RowBufferEntry probeColumn = CreateProbeColumn();

                JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
                joinAlgebraNode.ProbeBufferEntry  = probeColumn;
                joinAlgebraNode.Left  = input;
                joinAlgebraNode.Right = algebrizedQuery;
                joinAlgebraNode.Op    = expression.Negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin;
                SetLastAlgebraNode(joinAlgebraNode);

                return(CreateProbeColumnRef(probeColumn));
            }
        }
Example #28
0
            public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
            {
                if (node.Op != JoinAlgebraNode.JoinOperator.InnerJoin)
                {
                    _consistsOnlyOfInnerJoinsFiltersAndTables = false;
                    return(node);
                }

                if (node.Predicate != null)
                {
                    _filters.Add(node.Predicate);
                }

                Visit(node.Left);
                Visit(node.Right);

                return(node);
            }
Example #29
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			// A IJ (B J C) --> (A IJ B) J C

			node.Left = VisitAlgebraNode(node.Left);

			if (node.Op != JoinAlgebraNode.JoinOperator.InnerJoin)
				return node;

			JoinAlgebraNode rightSide = node.Right as JoinAlgebraNode;

			if (rightSide == null)
				return node;

			node.Right = rightSide.Left;
			rightSide.Left = node;

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

            RowBufferEntry[] outerReferences = AstUtil.GetOuterReferences(node);
            if (outerReferences != null && outerReferences.Length > 0)
            {
                _outerReferences.Push(node.OuterReferences);
            }

            node.Right = VisitAlgebraNode(node.Right);

            if (outerReferences != null && outerReferences.Length > 0)
            {
                _outerReferences.Pop();
            }

            return(node);
        }
Example #31
0
        public static bool JoinDoesNotDependOn(JoinAlgebraNode joinNode, AlgebraNode joinSide)
        {
            RowBufferEntry[] joinSideDefinedValues = GetDefinedValueEntries(joinSide);

            if (joinNode.Predicate != null)
            {
                RowBufferEntry[] referencedRowBufferEntries = GetRowBufferEntryReferences(joinNode.Predicate);

                foreach (RowBufferEntry joinSideDefinedValue in joinSideDefinedValues)
                {
                    if (ArrayHelpers.Contains(referencedRowBufferEntries, joinSideDefinedValue))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #32
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // A IJ (B J C) --> (A IJ B) J C

            node.Left = VisitAlgebraNode(node.Left);

            if (node.Op != JoinAlgebraNode.JoinOperator.InnerJoin)
            {
                return(node);
            }

            JoinAlgebraNode rightSide = node.Right as JoinAlgebraNode;

            if (rightSide == null)
            {
                return(node);
            }

            node.Right     = rightSide.Left;
            rightSide.Left = node;

            return(VisitAlgebraNode(rightSide));
        }
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            node.OutputList = RemovedUnneededRowBufferColumns(node.OutputList);

            if (node.Predicate != null)
            {
                AddNeededRowBufferEntryReferences(node.Predicate);
            }

            if (node.PassthruPredicate != null)
            {
                AddNeededRowBufferEntryReferences(node.PassthruPredicate);
            }

            if (node.OuterReferences != null)
            {
                foreach (RowBufferEntry outerReference in node.OuterReferences)
                {
                    AddNeededRowBufferEntry(outerReference);
                }
            }

            return(base.VisitJoinAlgebraNode(node));
        }
Example #34
0
        public override ExpressionNode VisitSingleRowSubselect(SingleRowSubselect expression)
        {
            AlgebraNode inputNode = GetOrCreateInput();
            ResultAlgebraNode algebrizedSubquery = Algebrizer.Convert(expression.Query);
            ResultAlgebraNode assertedSubquery = CreateAssertedSubquery(algebrizedSubquery);

            JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
            joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
            joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
            joinAlgebraNode.Left = inputNode;
            joinAlgebraNode.Right = assertedSubquery;
            SetLastAlgebraNode(joinAlgebraNode);

            return new RowBufferEntryExpression(assertedSubquery.OutputList[0]);
        }
Example #35
0
        public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
        {
            expression.Left = VisitExpression(expression.Left);
            ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query);

            ExpressionNode leftExpression = expression.Left;
            RowBufferEntryExpression rightExpression = new RowBufferEntryExpression();
            rightExpression.RowBufferEntry = algebrizedQuery.OutputList[0];

            ExpressionBuilder expressionBuilder = new ExpressionBuilder();
            expressionBuilder.Push(leftExpression);
            expressionBuilder.Push(rightExpression);
            expressionBuilder.PushBinary(expression.Op);

            bool negated = (expression.Type == AllAnySubselect.AllAnyType.All);
            if (negated)
            {
                expressionBuilder.PushUnary(UnaryOperator.LogicalNot);
                expressionBuilder.Push(leftExpression);
                expressionBuilder.PushIsNull();
                expressionBuilder.Push(rightExpression);
                expressionBuilder.PushIsNull();
                expressionBuilder.PushNAry(LogicalOperator.Or);
            }

            ExpressionNode filterPredicate = expressionBuilder.Pop();

            FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
            filterAlgebraNode.Input = algebrizedQuery;
            filterAlgebraNode.Predicate = filterPredicate;

            AlgebraNode input = GetAndResetLastNode();

            if (!negated && !ProbingEnabled && input == null)
            {
                SetLastAlgebraNode(filterAlgebraNode);
                return LiteralExpression.FromBoolean(true);
            }
            else
            {
                if (input == null)
                    input = CreateConstantScan();

                RowBufferEntry probeColumn = CreateProbeColumn();

                JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
                joinAlgebraNode.ProbeBufferEntry = probeColumn;
                joinAlgebraNode.Left = input;
                joinAlgebraNode.Right = filterAlgebraNode;
                joinAlgebraNode.Op = negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin;

                SetLastAlgebraNode(joinAlgebraNode);
                return CreateProbeColumnRef(probeColumn);
            }
        }
Example #36
0
        public override ExpressionNode VisitExistsSubselect(ExistsSubselect expression)
        {
            AlgebraNode input = GetAndResetLastNode();
            ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query);

            if (!expression.Negated && AstUtil.WillProduceAtLeastOneRow(algebrizedQuery))
            {
                if (input == null)
                    SetLastAlgebraNode(CreateConstantScan());
                else
                    SetLastAlgebraNode(input);

                return LiteralExpression.FromBoolean(true);
            }

            if (!expression.Negated && !ProbingEnabled && input == null)
            {
                SetLastAlgebraNode(algebrizedQuery);
                return LiteralExpression.FromBoolean(true);
            }
            else
            {
                if (input == null)
                    input = CreateConstantScan();

                RowBufferEntry probeColumn = CreateProbeColumn();

                JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
                joinAlgebraNode.ProbeBufferEntry = probeColumn;
                joinAlgebraNode.Left = input;
                joinAlgebraNode.Right = algebrizedQuery;
                joinAlgebraNode.Op = expression.Negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin;
                SetLastAlgebraNode(joinAlgebraNode);

                return CreateProbeColumnRef(probeColumn);
            }
        }
Example #37
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            if (node.Predicate == null || !AstUtil.ContainsSubselect(node.Predicate))
                return base.VisitJoinAlgebraNode(node);

            node.Left = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            switch (node.Op)
            {
                case JoinAlgebraNode.JoinOperator.InnerJoin:
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Predicate = node.Predicate;
                    filterAlgebraNode.Input = node;
                    node.Predicate = null;

                    SetLastAlgebraNode(node);
                    _probingEnabledStack.Push(false);
                    filterAlgebraNode.Predicate = VisitExpression(filterAlgebraNode.Predicate);
                    _probingEnabledStack.Pop();
                    filterAlgebraNode.Input = GetAndResetLastNode();

                    return filterAlgebraNode;

                }

                case JoinAlgebraNode.JoinOperator.LeftOuterJoin:
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Predicate = node.Predicate;
                    filterAlgebraNode.Input = node.Right;

                    node.Right = filterAlgebraNode;
                    node.Predicate = null;

                    SetLastAlgebraNode(filterAlgebraNode.Input);
                    _probingEnabledStack.Push(false);
                    filterAlgebraNode.Predicate = VisitExpression(filterAlgebraNode.Predicate);
                    _probingEnabledStack.Pop();
                    filterAlgebraNode.Input = GetAndResetLastNode();

                    return node;
                }

                case JoinAlgebraNode.JoinOperator.RightOuterJoin:
                {
                    node.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                    AlgebraNode oldLeft = node.Left;
                    node.Left = node.Right;
                    node.Right = oldLeft;
                    goto case JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                }

                case JoinAlgebraNode.JoinOperator.FullOuterJoin:
                    // TODO: Support subqueries in FULL OUTER JOIN.
                    throw ExceptionBuilder.InternalError("FULL OUTER JOIN containing a subselect predicate in ON clause is not supported.");

                default:
                    throw ExceptionBuilder.UnhandledCaseLabel(node.Op);
            }
        }
Example #38
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			// Get declared tables of left and right

			RowBufferEntry[] leftDefinedValues = AstUtil.GetDefinedValueEntries(node.Left);
			RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(node.Right);

			// Replace outer joins by left-/right-/inner joins

			if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin || 
			    node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
			{
				if (IsAnyNullRejected(leftDefinedValues))
				{
					if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin)
						node.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
					else
						node.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
				}
			}

			if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin ||
			    node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
			{
				if (IsAnyNullRejected(rightDefinedValues))
				{
					if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin)
						node.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
					else
						node.Op = JoinAlgebraNode.JoinOperator.RightOuterJoin;
				}
			}

			// After converting an outer join to an inner one we can
			// sometimes eliminate the whole join.

			if (node.Op == JoinAlgebraNode.JoinOperator.InnerJoin)
			{
				// TODO: There is a problem. If the constant scan defines values this does not work. Acutally, 
				//       this is currently no problem as the only way to create such a plan is using derived 
				//       tables and in this phase the child will be a ResultNode.

				if (node.Left is ConstantScanAlgebraNode)
					return VisitAlgebraNode(WrapWithFilter(node.Right, node.Predicate));

				if (node.Right is ConstantScanAlgebraNode)
					return VisitAlgebraNode(WrapWithFilter(node.Left, node.Predicate));
			}

			// Analyze AND-parts of Condition

			if (node.Predicate == null)
			{
				// TODO: This does not work as the children are not yet rearranged.
				if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin ||
				    node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin)
				{
					bool hasOuterReferences = AstUtil.GetOuterReferences(node).Length == 0;
					if (!hasOuterReferences)
					{
						if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin && AstUtil.WillProduceAtLeastOneRow(node.Right) ||
						    node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin && AstUtil.WillProduceAtLeastOneRow(node.Left))
						{
							node.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
							return VisitAlgebraNode(node);
						}
					}
				}
			}
			else
			{
				foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, node.Predicate))
				{
					if (node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin)
					{
						// Check if we can derive from this AND-part that a table it depends on
						// is null-rejected.

						RowBufferEntry[] rowBufferEntries = AstUtil.GetRowBufferEntryReferences(andPart);
						foreach (RowBufferEntry rowBufferEntry in rowBufferEntries)
						{
							if (AstUtil.ExpressionYieldsNullOrFalseIfRowBufferEntryNull(andPart, rowBufferEntry))
							{
								if (ArrayHelpers.Contains(leftDefinedValues, rowBufferEntry) &&
								    node.Op != JoinAlgebraNode.JoinOperator.LeftOuterJoin)
								{
									AddNullRejectedTable(rowBufferEntry);
								}
								else if (ArrayHelpers.Contains(rightDefinedValues, rowBufferEntry) &&
								         node.Op != JoinAlgebraNode.JoinOperator.RightOuterJoin)
								{
									AddNullRejectedTable(rowBufferEntry);
								}
							}
						}
					}
				}
			}

			// Visit children

			node.Left = VisitAlgebraNode(node.Left);
			node.Right = VisitAlgebraNode(node.Right);

			return node;
		}
Example #39
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 #40
0
		public static RowBufferEntry[] GetOuterReferences(JoinAlgebraNode node)
		{
			RowBufferEntry[] leftDefinedValues = GetDefinedValueEntries(node.Left);

			RowBufferEntry[] rowBufferEntries = GetRowBufferEntryReferences(node.Right);
			List<RowBufferEntry> outerReferenceList = new List<RowBufferEntry>();

			foreach (RowBufferEntry rightColumnDependency in rowBufferEntries)
			{
				if (ArrayHelpers.Contains(leftDefinedValues, rightColumnDependency))
					outerReferenceList.Add(rightColumnDependency);
			}

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

            // Reorder (pull LOJ out of IJ)
            //
            //  (A LOJ B) IJ C     --->    (A IJ C) LOJ B    (IJ does not depend on B)
            //  (A ROJ B) IJ C     --->    A ROJ (B IJ C)    (IJ does not depend on A)

            if (node.Op == JoinAlgebraNode.JoinOperator.InnerJoin)
            {
                JoinAlgebraNode childJoin = node.Left as JoinAlgebraNode;

                if (childJoin != null &&
                    (childJoin.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin ||
                     childJoin.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin))
                {
                    if (childJoin.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin)
                    {
                        if (AstUtil.JoinDoesNotDependOn(node, childJoin.Right))
                        {
                            node.Left      = childJoin.Left;
                            childJoin.Left = node;
                            return(VisitAlgebraNode(childJoin));
                        }
                    }
                    else if (childJoin.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin)
                    {
                        if (AstUtil.JoinDoesNotDependOn(node, childJoin.Left))
                        {
                            node.Left       = childJoin.Right;
                            childJoin.Right = node;
                            return(VisitAlgebraNode(childJoin));
                        }
                    }
                }
            }

            //// Reorder (push LSJ)
            ////
            ////  (A J B) LSJ C      --->    (A LSJ C) J B     (LSJ does not depend on B)
            ////  (A J B) LSJ C      --->     A J (B LSJ C)    (LSJ does not depend on A)

            //if (node.Op == JoinAlgebraNode.JoinOperator.LeftSemiJoin ||
            //    node.Op == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin)
            //{
            //    JoinAlgebraNode childJoin = node.Left as JoinAlgebraNode;
            //    if (childJoin != null)
            //    {
            //        if (AstUtil.JoinDoesNotDependOn(node, childJoin.Right))
            //        {
            //            node.Left = childJoin.Left;
            //            childJoin.Left = node;
            //            return VisitAlgebraNode(childJoin);
            //        }

            //        if (AstUtil.JoinDoesNotDependOn(node, childJoin.Left))
            //        {
            //            node.Left = childJoin.Right;
            //            childJoin.Right = node;
            //            return VisitAlgebraNode(childJoin);
            //        }
            //    }
            //}

            return(node);
        }
Example #42
0
		public static bool JoinDoesNotDependOn(JoinAlgebraNode joinNode, AlgebraNode joinSide)
		{
			RowBufferEntry[] joinSideDefinedValues = GetDefinedValueEntries(joinSide);

			if (joinNode.Predicate != null)
			{
				RowBufferEntry[] referencedRowBufferEntries = GetRowBufferEntryReferences(joinNode.Predicate);

				foreach (RowBufferEntry joinSideDefinedValue in joinSideDefinedValues)
				{
					if (ArrayHelpers.Contains(referencedRowBufferEntries, joinSideDefinedValue))
						return false;
				}
			}

			return true;
		}
Example #43
0
		public static bool AllowsRightPushDown(JoinAlgebraNode.JoinOperator joinOperator)
		{
			return joinOperator == JoinAlgebraNode.JoinOperator.InnerJoin ||
				   joinOperator == JoinAlgebraNode.JoinOperator.LeftOuterJoin ||
				   joinOperator == JoinAlgebraNode.JoinOperator.LeftSemiJoin ||
				   joinOperator == JoinAlgebraNode.JoinOperator.RightSemiJoin ||
				   joinOperator == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin ||
				   joinOperator == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin;
		}
Example #44
0
		public virtual AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			node.Left = VisitAlgebraNode(node.Left);
			node.Right = VisitAlgebraNode(node.Right);

			if (node.Predicate != null)
				node.Predicate = VisitExpression(node.Predicate);

			if (node.PassthruPredicate != null)
				node.PassthruPredicate = VisitExpression(node.PassthruPredicate);

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

            List<RowBufferEntry> outputList = new List<RowBufferEntry>();
            outputList.AddRange(node.Left.OutputList);
            outputList.AddRange(node.Right.OutputList);
            if (node.ProbeBufferEntry != null)
                outputList.Add(node.ProbeBufferEntry);
            node.OutputList = outputList.ToArray();

            return node;
        }
Example #46
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 #47
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 #48
0
		private void UpdatePredicateRowBufferReferences(NestedLoopsIterator nestedLoopsIterator, JoinAlgebraNode node)
		{
			BoundRowBufferEntrySet leftBoundRowBufferEntrySet = new BoundRowBufferEntrySet(nestedLoopsIterator.Left.RowBuffer, node.Left.OutputList);
			BoundRowBufferEntrySet rightBoundRowBufferEntrySet = new BoundRowBufferEntrySet(nestedLoopsIterator.Right.RowBuffer, node.Right.OutputList);

			if (node.Predicate != null)
				nestedLoopsIterator.Predicate = CreateRuntimeExpression(node.Predicate, leftBoundRowBufferEntrySet, rightBoundRowBufferEntrySet);

			if (node.PassthruPredicate != null)
				nestedLoopsIterator.PassthruPredicate = CreateRuntimeExpression(node.PassthruPredicate, leftBoundRowBufferEntrySet, rightBoundRowBufferEntrySet);
		}
Example #49
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			node.Left = VisitAlgebraNode(node.Left);
			node.Right = VisitAlgebraNode(node.Right);
            
			// Get defined values of left and right

			RowBufferEntry[] leftDefinedValues = AstUtil.GetDefinedValueEntries(node.Left);
			RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(node.Right);
            
			List<ExpressionNode> andPartsWithinJoin = new List<ExpressionNode>();

			// Try to pull up AND-parts that contain outer references from a left sided filter and combine 
			// them with the join predicate.
			//
			// NOTE: This is only possible if the join is not a LEFT OUTER or FULL OUTER JOIN since this
			// operation would change the join's semantic.

			if (node.Op != JoinAlgebraNode.JoinOperator.LeftOuterJoin &&
			    node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin)
			{
				FilterAlgebraNode leftAsFilter = node.Left as FilterAlgebraNode;
				if (leftAsFilter != null)
				{
					List<ExpressionNode> remainingAndParts = new List<ExpressionNode>();
					foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, leftAsFilter.Predicate))
					{
						if (AndPartHasOuterReference(andPart, leftDefinedValues))
							andPartsWithinJoin.Add(andPart);
						else
							remainingAndParts.Add(andPart);
					}

					leftAsFilter.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);
					if (leftAsFilter.Predicate == null)
						node.Left = leftAsFilter.Input;
				}
			}

			// Try to pull up AND-parts that contain outer references from a right sided filter and combine 
			// them with the join predicate.
			//
			// NOTE: This is only possible if the join is not a RIGHT OUTER or FULL OUTER JOIN since this
			// operation would change the join's semantic.

			if (node.Op != JoinAlgebraNode.JoinOperator.RightOuterJoin &&
			    node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin)
			{
				FilterAlgebraNode rightAsFilter = node.Right as FilterAlgebraNode;
				if (rightAsFilter != null)
				{
					List<ExpressionNode> remainingAndParts = new List<ExpressionNode>();
					foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, rightAsFilter.Predicate))
					{
						if (AndPartHasOuterReference(andPart, rightDefinedValues))
							andPartsWithinJoin.Add(andPart);
						else 
							remainingAndParts.Add(andPart);
					}

					rightAsFilter.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);
					if (rightAsFilter.Predicate == null)
						node.Right = rightAsFilter.Input;
				}
			}

			// If we found any AND-parts that could be pulled up, merge them with the join predicate.

			if (andPartsWithinJoin.Count > 0)
				node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, node.Predicate, AstUtil.CombineConditions(LogicalOperator.And, andPartsWithinJoin));

			// Now we try to extract AND-parts that contain outer references from the join predicate itself.
			//
			// NOTE: This is only possible if the node is not an OUTER JOIN. If the node is a SEMI JOIN the
			// operation is only legal if the AND-part does not reference any columns from the side that is
			// is used as filter criteria (i.e. for LSJ this is the right side, for RSJ this is the left
			// side).

			if (node.Op != JoinAlgebraNode.JoinOperator.LeftOuterJoin &&
			    node.Op != JoinAlgebraNode.JoinOperator.RightOuterJoin &&
			    node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin &&
			    node.Predicate != null)
			{
				List<ExpressionNode> andPartsAboveJoin = new List<ExpressionNode>();
				List<ExpressionNode> remainingAndParts = new List<ExpressionNode>();

				foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, node.Predicate))
				{
					if (AndPartHasOuterReference(andPart, leftDefinedValues, rightDefinedValues) && 
						SemiJoinDoesNotDependOn(node.Op, andPart, leftDefinedValues, rightDefinedValues))
						andPartsAboveJoin.Add(andPart);
					else
						remainingAndParts.Add(andPart);
				}

				node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);
                
				if (andPartsAboveJoin.Count > 0)
				{
					FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
					filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.And, andPartsAboveJoin);
					filterAlgebraNode.Input = node;
					return filterAlgebraNode;
				}
			}
                                    
			return node;
		}
Example #50
0
		public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements)
		{
			JoinAlgebraNode result = new JoinAlgebraNode();
			result.StatisticsIterator = StatisticsIterator;
			result.OutputList = ArrayHelpers.Clone(OutputList);
			result.Left = (AlgebraNode)_left.Clone(alreadyClonedElements);
			result.Right = (AlgebraNode)_right.Clone(alreadyClonedElements);
			result.Op = _op;
			if (_predicate != null)
				result.Predicate = (ExpressionNode)_predicate.Clone(alreadyClonedElements);
			result.OuterReferences = ArrayHelpers.Clone(_outerReferences);
			return result;
		}
Example #51
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 #52
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            // Get defined values of left and right

            RowBufferEntry[] leftDefinedValues  = AstUtil.GetDefinedValueEntries(node.Left);
            RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(node.Right);

            List <ExpressionNode> andPartsWithinJoin = new List <ExpressionNode>();

            // Try to pull up AND-parts that contain outer references from a left sided filter and combine
            // them with the join predicate.
            //
            // NOTE: This is only possible if the join is not a LEFT OUTER or FULL OUTER JOIN since this
            // operation would change the join's semantic.

            if (node.Op != JoinAlgebraNode.JoinOperator.LeftOuterJoin &&
                node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin)
            {
                FilterAlgebraNode leftAsFilter = node.Left as FilterAlgebraNode;
                if (leftAsFilter != null)
                {
                    List <ExpressionNode> remainingAndParts = new List <ExpressionNode>();
                    foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, leftAsFilter.Predicate))
                    {
                        if (AndPartHasOuterReference(andPart, leftDefinedValues))
                        {
                            andPartsWithinJoin.Add(andPart);
                        }
                        else
                        {
                            remainingAndParts.Add(andPart);
                        }
                    }

                    leftAsFilter.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);
                    if (leftAsFilter.Predicate == null)
                    {
                        node.Left = leftAsFilter.Input;
                    }
                }
            }

            // Try to pull up AND-parts that contain outer references from a right sided filter and combine
            // them with the join predicate.
            //
            // NOTE: This is only possible if the join is not a RIGHT OUTER or FULL OUTER JOIN since this
            // operation would change the join's semantic.

            if (node.Op != JoinAlgebraNode.JoinOperator.RightOuterJoin &&
                node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin)
            {
                FilterAlgebraNode rightAsFilter = node.Right as FilterAlgebraNode;
                if (rightAsFilter != null)
                {
                    List <ExpressionNode> remainingAndParts = new List <ExpressionNode>();
                    foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, rightAsFilter.Predicate))
                    {
                        if (AndPartHasOuterReference(andPart, rightDefinedValues))
                        {
                            andPartsWithinJoin.Add(andPart);
                        }
                        else
                        {
                            remainingAndParts.Add(andPart);
                        }
                    }

                    rightAsFilter.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);
                    if (rightAsFilter.Predicate == null)
                    {
                        node.Right = rightAsFilter.Input;
                    }
                }
            }

            // If we found any AND-parts that could be pulled up, merge them with the join predicate.

            if (andPartsWithinJoin.Count > 0)
            {
                node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, node.Predicate, AstUtil.CombineConditions(LogicalOperator.And, andPartsWithinJoin));
            }

            // Now we try to extract AND-parts that contain outer references from the join predicate itself.
            //
            // NOTE: This is only possible if the node is not an OUTER JOIN. If the node is a SEMI JOIN the
            // operation is only legal if the AND-part does not reference any columns from the side that is
            // is used as filter criteria (i.e. for LSJ this is the right side, for RSJ this is the left
            // side).

            if (node.Op != JoinAlgebraNode.JoinOperator.LeftOuterJoin &&
                node.Op != JoinAlgebraNode.JoinOperator.RightOuterJoin &&
                node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin &&
                node.Predicate != null)
            {
                List <ExpressionNode> andPartsAboveJoin = new List <ExpressionNode>();
                List <ExpressionNode> remainingAndParts = new List <ExpressionNode>();

                foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, node.Predicate))
                {
                    if (AndPartHasOuterReference(andPart, leftDefinedValues, rightDefinedValues) &&
                        SemiJoinDoesNotDependOn(node.Op, andPart, leftDefinedValues, rightDefinedValues))
                    {
                        andPartsAboveJoin.Add(andPart);
                    }
                    else
                    {
                        remainingAndParts.Add(andPart);
                    }
                }

                node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts);

                if (andPartsAboveJoin.Count > 0)
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.And, andPartsAboveJoin);
                    filterAlgebraNode.Input     = node;
                    return(filterAlgebraNode);
                }
            }

            return(node);
        }
Example #53
0
		private void PushOuterReferences(object[] rowBuffer, JoinAlgebraNode node)
		{
			if (node.OuterReferences != null && node.OuterReferences.Length > 0)
			{
				// Important: We cannot use node.OuterReferences as argument for BoundRowBufferEntrySet().
				// The replacment strategy below will replace occurences to the entries by their index
				// within the array. Therefore we need an array with the same layout as the row buffer.

				RowBufferEntry[] outerReferences = new RowBufferEntry[node.Left.OutputList.Length];
				for (int i = 0; i < outerReferences.Length; i++)
				{
					if (ArrayHelpers.Contains(node.OuterReferences, node.Left.OutputList[i]))
						outerReferences[i] = node.Left.OutputList[i];
				}

				BoundRowBufferEntrySet bufferEntrySet = new BoundRowBufferEntrySet(rowBuffer, outerReferences);
				_outerReferenceStack.Push(bufferEntrySet);
			}
		}
Example #54
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // Get declared tables of left and right

            RowBufferEntry[] leftDefinedValues  = AstUtil.GetDefinedValueEntries(node.Left);
            RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(node.Right);

            // Replace outer joins by left-/right-/inner joins

            if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
            {
                if (IsAnyNullRejected(leftDefinedValues))
                {
                    if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin)
                    {
                        node.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
                    }
                    else
                    {
                        node.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                    }
                }
            }

            if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
            {
                if (IsAnyNullRejected(rightDefinedValues))
                {
                    if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin)
                    {
                        node.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
                    }
                    else
                    {
                        node.Op = JoinAlgebraNode.JoinOperator.RightOuterJoin;
                    }
                }
            }

            // After converting an outer join to an inner one we can
            // sometimes eliminate the whole join.

            if (node.Op == JoinAlgebraNode.JoinOperator.InnerJoin)
            {
                // TODO: There is a problem. If the constant scan defines values this does not work. Acutally,
                //       this is currently no problem as the only way to create such a plan is using derived
                //       tables and in this phase the child will be a ResultNode.

                if (node.Left is ConstantScanAlgebraNode)
                {
                    return(VisitAlgebraNode(WrapWithFilter(node.Right, node.Predicate)));
                }

                if (node.Right is ConstantScanAlgebraNode)
                {
                    return(VisitAlgebraNode(WrapWithFilter(node.Left, node.Predicate)));
                }
            }

            // Analyze AND-parts of Condition

            if (node.Predicate == null)
            {
                // TODO: This does not work as the children are not yet rearranged.
                if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin ||
                    node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin)
                {
                    bool hasOuterReferences = AstUtil.GetOuterReferences(node).Length == 0;
                    if (!hasOuterReferences)
                    {
                        if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin && AstUtil.WillProduceAtLeastOneRow(node.Right) ||
                            node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin && AstUtil.WillProduceAtLeastOneRow(node.Left))
                        {
                            node.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
                            return(VisitAlgebraNode(node));
                        }
                    }
                }
            }
            else
            {
                foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, node.Predicate))
                {
                    if (node.Op != JoinAlgebraNode.JoinOperator.FullOuterJoin)
                    {
                        // Check if we can derive from this AND-part that a table it depends on
                        // is null-rejected.

                        RowBufferEntry[] rowBufferEntries = AstUtil.GetRowBufferEntryReferences(andPart);
                        foreach (RowBufferEntry rowBufferEntry in rowBufferEntries)
                        {
                            if (AstUtil.ExpressionYieldsNullOrFalseIfRowBufferEntryNull(andPart, rowBufferEntry))
                            {
                                if (ArrayHelpers.Contains(leftDefinedValues, rowBufferEntry) &&
                                    node.Op != JoinAlgebraNode.JoinOperator.LeftOuterJoin)
                                {
                                    AddNullRejectedTable(rowBufferEntry);
                                }
                                else if (ArrayHelpers.Contains(rightDefinedValues, rowBufferEntry) &&
                                         node.Op != JoinAlgebraNode.JoinOperator.RightOuterJoin)
                                {
                                    AddNullRejectedTable(rowBufferEntry);
                                }
                            }
                        }
                    }
                }
            }

            // Visit children

            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            return(node);
        }
Example #55
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin ||
				node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin ||
				node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin)
			{
				if (node.OuterReferences != null && node.OuterReferences.Length > 0)
					throw ExceptionBuilder.InternalError("Outer references should not be possible for {0} and are not supported.", node.Op);

				node.SwapSides();
			}

			NestedLoopsIterator nestedLoopsIterator;

			switch (node.Op)
			{
				case JoinAlgebraNode.JoinOperator.InnerJoin:
					nestedLoopsIterator = new InnerNestedLoopsIterator();
					break;
				case JoinAlgebraNode.JoinOperator.LeftOuterJoin:
					nestedLoopsIterator = new LeftOuterNestedLoopsIterator();
					break;
				case JoinAlgebraNode.JoinOperator.LeftSemiJoin:
					if (node.ProbeBufferEntry == null)
						nestedLoopsIterator = new LeftSemiNestedLoopsIterator();
					else
					{
						ProbedSemiJoinNestedLoopsIterator probedSemiJoinNestedLoopsIterator = new ProbedSemiJoinNestedLoopsIterator();
						probedSemiJoinNestedLoopsIterator.ProbeOutput = GetDefinedValue(node.OutputList, node.ProbeBufferEntry);
						nestedLoopsIterator = probedSemiJoinNestedLoopsIterator;
					}
					break;
				case JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin:
					if (node.ProbeBufferEntry == null)
						nestedLoopsIterator = new LeftAntiSemiNestedLoopsIterator();
					else
					{
						ProbedAntiSemiJoinNestedLoopsIterator probedSemiJoinNestedLoopsIterator = new ProbedAntiSemiJoinNestedLoopsIterator();
						probedSemiJoinNestedLoopsIterator.ProbeOutput = GetDefinedValue(node.OutputList, node.ProbeBufferEntry);
						nestedLoopsIterator = probedSemiJoinNestedLoopsIterator;
					}
					break;
				default:
					throw ExceptionBuilder.UnhandledCaseLabel(node.Op);
			}

			nestedLoopsIterator.RowBuffer = new object[node.OutputList.Length];
			nestedLoopsIterator.Left = ConvertAlgebraNode(node.Left);
			nestedLoopsIterator.LeftOutput = GetIteratorOutput(0, node.Left.OutputList, node.OutputList);

			PushOuterReferences(nestedLoopsIterator.Left.RowBuffer, node);

			nestedLoopsIterator.Right = ConvertAlgebraNode(node.Right);
			nestedLoopsIterator.RightOutput = GetIteratorOutput(nestedLoopsIterator.LeftOutput.Length, node.Right.OutputList, node.OutputList);

			UpdatePredicateRowBufferReferences(nestedLoopsIterator, node);

			if (node.OuterReferences != null && node.OuterReferences.Length > 0)
				_outerReferenceStack.Pop();

			SetLastIterator(node, nestedLoopsIterator);

			return node;
		}
Example #56
0
		public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
		{
			// Check if node only consists of INNER join nodes and simple table reference nodes.
			// This algorithm assumes that the table references have been lineraized so that
			//
			// - JoinedTableReference appear on the LHS only (the last one must be NamedTableReference ovbiviously)
			// - NamedTableReference appear on the RHS only
			//
			// While scanning the node's children we create a list of all JoinedTableReferences and
			// NamedTableReferences.

			InnerJoinTableExtractor innerJoinTableExtractor = new InnerJoinTableExtractor();
			innerJoinTableExtractor.Visit(node);

			if (!innerJoinTableExtractor.ConsistsOnlyOfInnerJoinsFiltersAndTables)
			{
				node.Left = VisitAlgebraNode(node.Left);
				node.Right = VisitAlgebraNode(node.Right);
				return node;                
			}
			else
			{
				TableAlgebraNode[] algebraNodes = innerJoinTableExtractor.GetTableNodes();
				Dictionary<TableRefBinding,TableAlgebraNode> tableRefToNodeDictionary = new Dictionary<TableRefBinding, TableAlgebraNode>();
				List<TableRefBinding> tableList = new List<TableRefBinding>();
				foreach (TableAlgebraNode algebraNode in algebraNodes)
				{
					tableRefToNodeDictionary.Add(algebraNode.TableRefBinding, algebraNode);
					tableList.Add(algebraNode.TableRefBinding);
				}

				// Create a mapping RowBufferEntry -> ColumnRefBinding

				Dictionary<RowBufferEntry, ColumnRefBinding> rowBufferColumnDictionary = new Dictionary<RowBufferEntry, ColumnRefBinding>();
				foreach (TableRefBinding tableRefBinding in tableList)
				{
					foreach (ColumnRefBinding columnRefBinding in tableRefBinding.ColumnRefs)
						rowBufferColumnDictionary.Add(columnRefBinding.ValueDefinition.Target, columnRefBinding);
				}

				// Create list of all possible join conditions and remaining AND-parts.

				List<JoinCondition> joinConditionList = new List<JoinCondition>();
				List<ExpressionNode> andPartList = new List<ExpressionNode>();

				ExpressionNode filter = AstUtil.CombineConditions(LogicalOperator.And, innerJoinTableExtractor.GetFilters());

				foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, filter))
				{
					JoinCondition joinCondition = ConvertToJoinCondition(rowBufferColumnDictionary, andPart);

					if (joinCondition != null)
						joinConditionList.Add(joinCondition);
					else
						andPartList.Add(andPart);
				}

				// After creating the list of all join conditions and AND-parts we have all we need to create
				// an optimimal join order between all tables of this part of the table tree.
				JoinOrder bestJoinOrder = GetBestJoinOrder(tableList.ToArray(), joinConditionList.ToArray(), andPartList.ToArray());

				// Get all tables that are introduced by this join order
                
				Dictionary<RowBufferEntry, ColumnValueDefinition> introducedColumns = GetIntroducedColumns(bestJoinOrder);

				// Combine AND-part list with all unused join conditions.

				andPartList.AddRange(bestJoinOrder.UnusedConditions);

				// Now we will re-create this part of the tree using the this join order.

				AlgebraNode lastAlgebraNode = null;
				for (int joinIndex = 0; joinIndex < bestJoinOrder.Joins.Length; joinIndex++)
				{
					Join join = bestJoinOrder.Joins[joinIndex];

					AlgebraNode tableInput;
					TableAlgebraNode tableNode = tableRefToNodeDictionary[join.TableRefBinding];

					ExpressionNode tableFilter = ExtractConditionsApplicableToTable(introducedColumns, andPartList, join.TableRefBinding);
					if (tableFilter == null)
					{
						tableInput = tableNode;
					}
					else
					{
						FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
						filterAlgebraNode.Input = tableNode;
						filterAlgebraNode.Predicate = tableFilter;
						tableInput = filterAlgebraNode;
					}

					if (lastAlgebraNode == null)
					{
						// This was the first one.
						lastAlgebraNode = tableInput;
					}
					else
					{
						// Not the first one, we can create a join with the current table reference
						// and last table reference.

						// Get all AND-parts that can be applied to the tables already joined.
						// This expression is merged to one condition.
						ExpressionNode[] applicableAndParts = GetAndPartsApplicableToJoin(introducedColumns, bestJoinOrder, joinIndex, andPartList, true);
						ExpressionNode condition = AstUtil.CombineConditions(LogicalOperator.And, applicableAndParts);

						ExpressionNode joinCondition;
						if (join.JoinCondition == null)
							joinCondition = null;
						else
							joinCondition = join.JoinCondition.ToExpression();

						ExpressionNode completeCondition = AstUtil.CombineConditions(LogicalOperator.And, condition, joinCondition);

						JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
						joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
						joinAlgebraNode.Left = lastAlgebraNode;
						joinAlgebraNode.Right = tableInput;
						joinAlgebraNode.Predicate = completeCondition;

						// Next time this newly created join is the last table reference.
						lastAlgebraNode = joinAlgebraNode;
					}
				}

				return lastAlgebraNode;
			}
		}
Example #57
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 #58
0
			public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
			{
				if (node.Op != JoinAlgebraNode.JoinOperator.InnerJoin)
				{
					_consistsOnlyOfInnerJoinsFiltersAndTables = false;
					return node;
				}

				if (node.Predicate != null)
					_filters.Add(node.Predicate);

				Visit(node.Left);
				Visit(node.Right);
                
				return node;
			}
Example #59
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // Check if node only consists of INNER join nodes and simple table reference nodes.
            // This algorithm assumes that the table references have been lineraized so that
            //
            // - JoinedTableReference appear on the LHS only (the last one must be NamedTableReference ovbiviously)
            // - NamedTableReference appear on the RHS only
            //
            // While scanning the node's children we create a list of all JoinedTableReferences and
            // NamedTableReferences.

            InnerJoinTableExtractor innerJoinTableExtractor = new InnerJoinTableExtractor();

            innerJoinTableExtractor.Visit(node);

            if (!innerJoinTableExtractor.ConsistsOnlyOfInnerJoinsFiltersAndTables)
            {
                node.Left  = VisitAlgebraNode(node.Left);
                node.Right = VisitAlgebraNode(node.Right);
                return(node);
            }
            else
            {
                TableAlgebraNode[] algebraNodes = innerJoinTableExtractor.GetTableNodes();
                Dictionary <TableRefBinding, TableAlgebraNode> tableRefToNodeDictionary = new Dictionary <TableRefBinding, TableAlgebraNode>();
                List <TableRefBinding> tableList = new List <TableRefBinding>();
                foreach (TableAlgebraNode algebraNode in algebraNodes)
                {
                    tableRefToNodeDictionary.Add(algebraNode.TableRefBinding, algebraNode);
                    tableList.Add(algebraNode.TableRefBinding);
                }

                // Create a mapping RowBufferEntry -> ColumnRefBinding

                Dictionary <RowBufferEntry, ColumnRefBinding> rowBufferColumnDictionary = new Dictionary <RowBufferEntry, ColumnRefBinding>();
                foreach (TableRefBinding tableRefBinding in tableList)
                {
                    foreach (ColumnRefBinding columnRefBinding in tableRefBinding.ColumnRefs)
                    {
                        rowBufferColumnDictionary.Add(columnRefBinding.ValueDefinition.Target, columnRefBinding);
                    }
                }

                // Create list of all possible join conditions and remaining AND-parts.

                List <JoinCondition>  joinConditionList = new List <JoinCondition>();
                List <ExpressionNode> andPartList       = new List <ExpressionNode>();

                ExpressionNode filter = AstUtil.CombineConditions(LogicalOperator.And, innerJoinTableExtractor.GetFilters());

                foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, filter))
                {
                    JoinCondition joinCondition = ConvertToJoinCondition(rowBufferColumnDictionary, andPart);

                    if (joinCondition != null)
                    {
                        joinConditionList.Add(joinCondition);
                    }
                    else
                    {
                        andPartList.Add(andPart);
                    }
                }

                // After creating the list of all join conditions and AND-parts we have all we need to create
                // an optimimal join order between all tables of this part of the table tree.
                JoinOrder bestJoinOrder = GetBestJoinOrder(tableList.ToArray(), joinConditionList.ToArray(), andPartList.ToArray());

                // Get all tables that are introduced by this join order

                Dictionary <RowBufferEntry, ColumnValueDefinition> introducedColumns = GetIntroducedColumns(bestJoinOrder);

                // Combine AND-part list with all unused join conditions.

                andPartList.AddRange(bestJoinOrder.UnusedConditions);

                // Now we will re-create this part of the tree using the this join order.

                AlgebraNode lastAlgebraNode = null;
                for (int joinIndex = 0; joinIndex < bestJoinOrder.Joins.Length; joinIndex++)
                {
                    Join join = bestJoinOrder.Joins[joinIndex];

                    AlgebraNode      tableInput;
                    TableAlgebraNode tableNode = tableRefToNodeDictionary[join.TableRefBinding];

                    ExpressionNode tableFilter = ExtractConditionsApplicableToTable(introducedColumns, andPartList, join.TableRefBinding);
                    if (tableFilter == null)
                    {
                        tableInput = tableNode;
                    }
                    else
                    {
                        FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                        filterAlgebraNode.Input     = tableNode;
                        filterAlgebraNode.Predicate = tableFilter;
                        tableInput = filterAlgebraNode;
                    }

                    if (lastAlgebraNode == null)
                    {
                        // This was the first one.
                        lastAlgebraNode = tableInput;
                    }
                    else
                    {
                        // Not the first one, we can create a join with the current table reference
                        // and last table reference.

                        // Get all AND-parts that can be applied to the tables already joined.
                        // This expression is merged to one condition.
                        ExpressionNode[] applicableAndParts = GetAndPartsApplicableToJoin(introducedColumns, bestJoinOrder, joinIndex, andPartList, true);
                        ExpressionNode   condition          = AstUtil.CombineConditions(LogicalOperator.And, applicableAndParts);

                        ExpressionNode joinCondition;
                        if (join.JoinCondition == null)
                        {
                            joinCondition = null;
                        }
                        else
                        {
                            joinCondition = join.JoinCondition.ToExpression();
                        }

                        ExpressionNode completeCondition = AstUtil.CombineConditions(LogicalOperator.And, condition, joinCondition);

                        JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                        joinAlgebraNode.Op        = JoinAlgebraNode.JoinOperator.InnerJoin;
                        joinAlgebraNode.Left      = lastAlgebraNode;
                        joinAlgebraNode.Right     = tableInput;
                        joinAlgebraNode.Predicate = completeCondition;

                        // Next time this newly created join is the last table reference.
                        lastAlgebraNode = joinAlgebraNode;
                    }
                }

                return(lastAlgebraNode);
            }
        }
Example #60
0
        public override TableReference VisitJoinedTableReference(JoinedTableReference node)
        {
            TableReference nonCteTableRef;

            if (IsTableReferenceToCurrentCommonTableBinding(node.Left))
            {
                nonCteTableRef = node.Right;
            }
            else if (IsTableReferenceToCurrentCommonTableBinding(node.Right))
            {
                nonCteTableRef = node.Left;
            }
            else
            {
                nonCteTableRef = null;
            }

            if (nonCteTableRef != null)
            {
                Debug.Assert(node.JoinType == JoinType.Inner);
                AlgebraNode algebrizedPath = ConvertAstNode(nonCteTableRef);
                SetLastAlgebraNode(algebrizedPath);

                if (node.Condition != null)
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Input     = GetLastAlgebraNode();
                    filterAlgebraNode.Predicate = node.Condition;
                    SetLastAlgebraNode(filterAlgebraNode);
                }
                return(node);
            }

            JoinAlgebraNode algebraNode = new JoinAlgebraNode();

            algebraNode.Left      = ConvertAstNode(node.Left);
            algebraNode.Right     = ConvertAstNode(node.Right);
            algebraNode.Predicate = node.Condition;

            switch (node.JoinType)
            {
            case JoinType.Inner:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
                break;

            case JoinType.LeftOuter:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                break;

            case JoinType.RightOuter:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.RightOuterJoin;
                break;

            case JoinType.FullOuter:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.FullOuterJoin;
                break;
            }

            SetLastAlgebraNode(algebraNode);
            return(node);
        }