Esempio n. 1
0
 private void AddNullRejectedTable(RowBufferEntry rowBufferEntries)
 {
     if (!_nullRejectedRowBufferEntries.Contains(rowBufferEntries))
     {
         _nullRejectedRowBufferEntries.Add(rowBufferEntries);
     }
 }
Esempio n. 2
0
			public void Add(AggregateExpression aggregateExpression)
			{
				AggregateExpression matchingAggregateExpression = null;
				foreach (AggregateExpression existingAggregateExpression in _aggregateExpressions)
				{
					if (existingAggregateExpression.IsStructuralEqualTo(aggregateExpression))
					{
						matchingAggregateExpression = existingAggregateExpression;
						break;
					}
				}

				if (matchingAggregateExpression != null)
				{
					aggregateExpression.ValueDefinition = matchingAggregateExpression.ValueDefinition;
				}
				else
				{
					RowBufferEntry rowBufferEntry = new RowBufferEntry(aggregateExpression.Aggregator.ReturnType);

					AggregatedValueDefinition aggregatedValueDefinition = new AggregatedValueDefinition();
					aggregatedValueDefinition.Target = rowBufferEntry;
					aggregatedValueDefinition.Aggregate = aggregateExpression.Aggregate;
					aggregatedValueDefinition.Aggregator = aggregateExpression.Aggregator;
					aggregatedValueDefinition.Argument = aggregateExpression.Argument;
					aggregateExpression.ValueDefinition = aggregatedValueDefinition;
					_aggregateExpressions.Add(aggregateExpression);
				}
			}
Esempio n. 3
0
        private static void CreateBufferedValue(ExpressionNode expression, ICollection <ComputedValueDefinition> computedColumnList, ICollection <RowBufferEntry> columnList, IEnumerable <ComputedValueDefinition> alreadyComputedBufferedValues)
        {
            if (alreadyComputedBufferedValues != null)
            {
                expression = ReplaceAlreadyComputedSubsequences(expression, alreadyComputedBufferedValues);
            }

            foreach (ComputedValueDefinition computedBufferedValue in computedColumnList)
            {
                if (expression.IsStructuralEqualTo(computedBufferedValue.Expression))
                {
                    columnList.Add(computedBufferedValue.Target);
                    return;
                }
            }

            RowBufferEntryExpression rowBufferExpression = expression as RowBufferEntryExpression;

            if (rowBufferExpression != null)
            {
                columnList.Add(rowBufferExpression.RowBufferEntry);
            }
            else
            {
                RowBufferEntry rowBufferEntry = new RowBufferEntry(expression.ExpressionType);
                columnList.Add(rowBufferEntry);

                ComputedValueDefinition computedValue = new ComputedValueDefinition();
                computedValue.Target     = rowBufferEntry;
                computedValue.Expression = expression;
                computedColumnList.Add(computedValue);
            }
        }
Esempio n. 4
0
		private void CreateColumnRefs()
		{
			List<ColumnRefBinding> tableColumnRefs = new List<ColumnRefBinding>();

			if (!(_definition is DerivedTableBinding) && !(_definition is CommonTableBinding))
			{
				// Create special row column ref

				ColumnRefBinding rowColumnRefBinding = CreateRowColumnRefBinding(this);
				tableColumnRefs.Add(rowColumnRefBinding);
			}

			// Create all column refs.

			foreach (ColumnBinding columnDefinition in _definition.Columns)
			{
				ColumnRefBinding columnRefBinding = new ColumnRefBinding(this, columnDefinition);

				RowBufferEntry rowBufferEntry = new RowBufferEntry(columnRefBinding.ColumnBinding.DataType);
				rowBufferEntry.Name = columnRefBinding.GetFullName();

				ColumnValueDefinition columnValueDefinition = new ColumnValueDefinition();
				columnValueDefinition.Target = rowBufferEntry;
				columnValueDefinition.ColumnRefBinding = columnRefBinding;

				columnRefBinding.ValueDefinition = columnValueDefinition;
				tableColumnRefs.Add(columnRefBinding);
			}

			// Assign column refs to table ref.

			_columnRefs = tableColumnRefs.ToArray();
		}
Esempio n. 5
0
            public void Add(AggregateExpression aggregateExpression)
            {
                AggregateExpression matchingAggregateExpression = null;

                foreach (AggregateExpression existingAggregateExpression in _aggregateExpressions)
                {
                    if (existingAggregateExpression.IsStructuralEqualTo(aggregateExpression))
                    {
                        matchingAggregateExpression = existingAggregateExpression;
                        break;
                    }
                }

                if (matchingAggregateExpression != null)
                {
                    aggregateExpression.ValueDefinition = matchingAggregateExpression.ValueDefinition;
                }
                else
                {
                    RowBufferEntry rowBufferEntry = new RowBufferEntry(aggregateExpression.Aggregator.ReturnType);

                    AggregatedValueDefinition aggregatedValueDefinition = new AggregatedValueDefinition();
                    aggregatedValueDefinition.Target     = rowBufferEntry;
                    aggregatedValueDefinition.Aggregate  = aggregateExpression.Aggregate;
                    aggregatedValueDefinition.Aggregator = aggregateExpression.Aggregator;
                    aggregatedValueDefinition.Argument   = aggregateExpression.Argument;
                    aggregateExpression.ValueDefinition  = aggregatedValueDefinition;
                    _aggregateExpressions.Add(aggregateExpression);
                }
            }
Esempio n. 6
0
        public override AlgebraNode VisitFilterAlgebraNode(FilterAlgebraNode node)
        {
            node.Input = VisitAlgebraNode(node.Input);

            ExpressionNode originalPredicate = (ExpressionNode) node.Predicate.Clone();
            SpoolExpressionExtractor spoolExpressionExtractor = new SpoolExpressionExtractor(_outerReferences);
            // HACK: This hack ensures that TRUE literals introduced by SpoolExpressionExtractor are removed.
            node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, spoolExpressionExtractor.VisitExpression(node.Predicate));
            SpoolExpression[] spoolExpressions = spoolExpressionExtractor.GetSpoolExpressions();

            // Now we must check that the remaining filter incl. input to the filter don't reference any other
            // outer reference.

            bool remainingFilterHasDependenciesToOuterReferences = CheckIfNodeHasDependenciesToOuterReferences(node);

            if (remainingFilterHasDependenciesToOuterReferences)
            {
                // OK; we cannot insert a spool operation here. Undo the expression replacement.
                node.Predicate = originalPredicate;
            }
            else if (spoolExpressions.Length > 0)
            {
                SpoolExpression spoolExpression = spoolExpressions[0];

                AlgebraNode currentInput;

                if (node.Predicate is ConstantExpression)
                    currentInput = node.Input;
                else
                    currentInput = node;

                RowBufferEntry indexEntry;
                RowBufferEntryExpression indexExpressionAsRowBufferEntryExpression = spoolExpression.IndexExpression as RowBufferEntryExpression;

                if (indexExpressionAsRowBufferEntryExpression != null)
                {
                    indexEntry = indexExpressionAsRowBufferEntryExpression.RowBufferEntry;
                }
                else
                {
                    indexEntry = new RowBufferEntry(spoolExpression.IndexExpression.ExpressionType);
                    ComputedValueDefinition definedValue = new ComputedValueDefinition();
                    definedValue.Target = indexEntry;
                    definedValue.Expression = spoolExpression.IndexExpression;

                    ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                    computeScalarAlgebraNode.Input = currentInput;
                    computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { definedValue };
                    currentInput = computeScalarAlgebraNode;
                }

                IndexSpoolAlgebraNode indexSpoolAlgebraNode = new IndexSpoolAlgebraNode();
                indexSpoolAlgebraNode.Input = currentInput;
                indexSpoolAlgebraNode.IndexEntry = indexEntry;
                indexSpoolAlgebraNode.ProbeExpression = spoolExpression.ProbeExpression;
                return indexSpoolAlgebraNode;
            }

            return node;
        }
Esempio n. 7
0
        public override QueryNode VisitSortedQuery(SortedQuery query)
        {
            ResultAlgebraNode input = (ResultAlgebraNode)ConvertAstNode(query.Input);

            List <RowBufferEntry> sortColumns = new List <RowBufferEntry>();
            List <SortOrder>      sortOrders  = new List <SortOrder>();

            foreach (OrderByColumn orderByColumn in query.OrderByColumns)
            {
                RowBufferEntry sortColumn = input.OutputList[orderByColumn.ColumnIndex];
                sortColumns.Add(sortColumn);
                sortOrders.Add(orderByColumn.SortOrder);
            }

            SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();

            sortAlgebraNode.Input       = input.Input;
            sortAlgebraNode.SortEntries = sortColumns.ToArray();
            sortAlgebraNode.SortOrders  = sortOrders.ToArray();
            input.Input = sortAlgebraNode;

            SetLastAlgebraNode(input);

            return(query);
        }
Esempio n. 8
0
        public override TableReference VisitDerivedTableReference(DerivedTableReference node)
        {
            AlgebraNode algebrizedQuery = Convert(node.Query);

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

            for (int i = 0; i < node.DerivedTableBinding.ColumnRefs.Length; i++)
            {
                RowBufferEntry targetRowBufferEntry = node.DerivedTableBinding.ColumnRefs[i].ValueDefinition.Target;
                RowBufferEntry sourceRowBufferEntry = algebrizedQuery.OutputList[i];

                ComputedValueDefinition definedValue = new ComputedValueDefinition();
                definedValue.Target     = targetRowBufferEntry;
                definedValue.Expression = new RowBufferEntryExpression(sourceRowBufferEntry);
                definedValues.Add(definedValue);
            }

            ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();

            computeScalarAlgebraNode.Input         = algebrizedQuery;
            computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
            SetLastAlgebraNode(computeScalarAlgebraNode);

            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);
        }
Esempio n. 10
0
 private void AddNeededRowBufferEntry(RowBufferEntry rowBufferEntry)
 {
     if (!IsNeeded(rowBufferEntry))
     {
         _neededRowBufferColumns.Add(rowBufferEntry);
     }
 }
Esempio n. 11
0
            private RowBufferEntry ReplaceRowBuffer(RowBufferEntry oldRowBufferEntry)
            {
                RowBufferEntry newRowBufferEntry;

                if (_rowBufferMappings.TryGetValue(oldRowBufferEntry, out newRowBufferEntry))
                {
                    return(newRowBufferEntry);
                }
                return(oldRowBufferEntry);
            }
Esempio n. 12
0
		private static bool AndPartHasOuterReference(ExpressionNode andPart, RowBufferEntry[] definedValues)
		{
			RowBufferEntry[] rowBufferEntries = AstUtil.GetRowBufferEntryReferences(andPart);
			foreach (RowBufferEntry rowBufferEntry in rowBufferEntries)
			{
				if (!ArrayHelpers.Contains(definedValues, rowBufferEntry))
					return true;
			}

			return false;
		}
Esempio n. 13
0
        private RowBufferEntry CreateProbeColumn()
        {
            if (!ProbingEnabled)
            {
                return(null);
            }

            RowBufferEntry probeColumn = new RowBufferEntry(typeof(bool));

            return(probeColumn);
        }
Esempio n. 14
0
        private RowBufferEntry ReplaceRowBufferEntry(RowBufferEntry rowBufferEntry)
        {
            RowBufferEntry replacementEntry;

            if (_inliningDictionary.TryGetValue(rowBufferEntry, out replacementEntry))
            {
                return(replacementEntry);
            }

            return(rowBufferEntry);
        }
Esempio n. 15
0
        private ExpressionNode CreateProbeColumnRef(RowBufferEntry probeColumn)
        {
            if (!ProbingEnabled)
            {
                return(LiteralExpression.FromBoolean(true));
            }

            RowBufferEntryExpression probeColumnRef = new RowBufferEntryExpression(probeColumn);

            return(probeColumnRef);
        }
Esempio n. 16
0
        private void NameEntry(RowBufferEntry target, string formatString)
        {
            if (!_rowBufferEntries.Contains(target))
            {
                if (target.Name == null)
                {
                    target.Name = String.Format(CultureInfo.InvariantCulture, formatString, 1000 + _rowBufferEntries.Count);
                }

                _rowBufferEntries.Add(target);
            }
        }
Esempio n. 17
0
            private bool IsOuterReference(RowBufferEntry entry)
            {
                foreach (RowBufferEntry[] outerReferences in _outerReferences)
                {
                    if (ArrayHelpers.Contains(outerReferences, entry))
                    {
                        return(true);
                    }
                }

                return(false);
            }
Esempio n. 18
0
		private static ColumnRefBinding CreateRowColumnRefBinding(TableRefBinding tableRefBinding)
		{
			RowColumnBinding rowColumnBinding = new RowColumnBinding(tableRefBinding.TableBinding);
			ColumnRefBinding rowColumnRefBinding = new ColumnRefBinding(tableRefBinding, rowColumnBinding);

			RowBufferEntry rowColumnBufferEntry = new RowBufferEntry(rowColumnRefBinding.ColumnBinding.DataType);
			rowColumnBufferEntry.Name = rowColumnRefBinding.TableRefBinding.Name;

			ColumnValueDefinition rowColumnValueDefinition = new ColumnValueDefinition();
			rowColumnValueDefinition.Target = rowColumnBufferEntry;
			rowColumnValueDefinition.ColumnRefBinding = rowColumnRefBinding;

			rowColumnRefBinding.ValueDefinition = rowColumnValueDefinition;
			return rowColumnRefBinding;
		}
Esempio n. 19
0
        private static void WriteRowBufferEntry(PropertyListBuilder builder, RowBufferEntry rowBufferColumn)
        {
            string[] parts = rowBufferColumn.Name.Split('.');
            if (parts.Length != 2)
            {
                builder.Write(Resources.ShowPlanKeyColumn, rowBufferColumn.Name);
            }
            else
            {
                builder.Write(Resources.ShowPlanKeyTable, parts[0]);
                builder.Write(Resources.ShowPlanKeyColumn, parts[1]);
            }

            builder.Write(Resources.ShowPlanKeyDataType, rowBufferColumn.DataType.Name);
        }
Esempio n. 20
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;
		}
Esempio n. 21
0
            public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
            {
                if (expression.Op == BinaryOperator.LogicalAnd)
                {
                    return(base.VisitBinaryExpression(expression));
                }
                else if (expression.Op == BinaryOperator.Equal)
                {
                    RowBufferEntry[] leftRowBufferEntries  = AstUtil.GetRowBufferEntryReferences(expression.Left);
                    RowBufferEntry[] rightRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Right);

                    if (leftRowBufferEntries.Length == 1 && rightRowBufferEntries.Length == 1)
                    {
                        RowBufferEntry leftRowBufferEntry  = leftRowBufferEntries[0];
                        RowBufferEntry rightRowBufferEntry = rightRowBufferEntries[0];

                        if (leftRowBufferEntry != rightRowBufferEntry)
                        {
                            // Both expressions depend on extactly one row buffer entry but
                            // they are not refering to the same row buffer entry.

                            bool leftDependsOnLeft   = ArrayHelpers.Contains(_leftDefinedEntries, leftRowBufferEntry);
                            bool rightDependsOnRight = ArrayHelpers.Contains(_rightDefinedEntries, rightRowBufferEntry);

                            bool leftDependsOnRight = ArrayHelpers.Contains(_rightDefinedEntries, leftRowBufferEntry);
                            bool rightDependsOnLeft = ArrayHelpers.Contains(_leftDefinedEntries, rightRowBufferEntry);

                            if (leftDependsOnRight && rightDependsOnLeft)
                            {
                                ExpressionNode oldLeft = expression.Left;
                                expression.Left     = expression.Right;
                                expression.Right    = oldLeft;
                                leftDependsOnLeft   = true;
                                rightDependsOnRight = true;
                            }

                            if (leftDependsOnLeft && rightDependsOnRight)
                            {
                                _equalPredicates.Add(expression);
                                return(LiteralExpression.FromBoolean(true));
                            }
                        }
                    }
                }

                return(expression);
            }
Esempio n. 22
0
        private static AlgebraNode InstantiateCte(AlgebraNode algebrizedCte, CommonTableBinding commonTableBinding, TableRefBinding commonTableRefBinding)
        {
            // Replace row buffers to base tables by new ones. This must be done because a CTE could be referenced multiple times.
            // Since same row buffer entries means that the underlying data will be stored in the same physical data slot this
            // will lead to problems if, for example, two instances of the same CTE are joined together. Any join condition that
            // operates on the same column will always compare data coming from the same join side (and therefor will always
            // evaluate to true).
            //
            // Some notes on the implementation:
            //
            //      1. Note that just replacing references to row buffers of base tables in RowBufferExpression is not enough;
            //         instead they must also be replaced in output lists, defined value references (esp. ConcatAlgebraNode) etc.
            //      2. Also note that although the QueryNodes are re-algebrized every time a CTE is references the expressions
            //         are still copied from the QueryNodes (instead of cloned). Therefore two algrebrized CTEs will share the same
            //         expression AST instances. That means that replacing the row buffers leads to failure.

            // HACK: This is a workaround for issue 2. However,
            //       I am not quite sure how one should implement row buffer entry replacement without cloning the algebrized query.
            algebrizedCte = (AlgebraNode)algebrizedCte.Clone();

            CteTableDefinedValuesReinitializer cteTableDefinedValuesReinitializer = new CteTableDefinedValuesReinitializer();

            cteTableDefinedValuesReinitializer.Visit(algebrizedCte);

            RowBufferEntry[] outputList = algebrizedCte.OutputList;
            int skipRecursionLevel      = commonTableBinding.IsRecursive ? 1 : 0;

            // Rename the query columns to the CTE columns
            List <ComputedValueDefinition> definedValues = new List <ComputedValueDefinition>();

            for (int i = 0; i < commonTableRefBinding.ColumnRefs.Length; i++)
            {
                RowBufferEntry targetRowBufferEntry = commonTableRefBinding.ColumnRefs[i].ValueDefinition.Target;
                RowBufferEntry sourceRowBufferEntry = outputList[i + skipRecursionLevel];

                ComputedValueDefinition definedValue = new ComputedValueDefinition();
                definedValue.Target     = targetRowBufferEntry;
                definedValue.Expression = new RowBufferEntryExpression(sourceRowBufferEntry);
                definedValues.Add(definedValue);
            }

            ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();

            computeScalarAlgebraNode.Input         = algebrizedCte;
            computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
            return(computeScalarAlgebraNode);
        }
Esempio n. 23
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));
            }
        }
Esempio n. 24
0
            public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
            {
                if (expression.Op == BinaryOperator.LogicalAnd)
                {
                    return(base.VisitBinaryExpression(expression));
                }
                else if (expression.Op == BinaryOperator.Equal)
                {
                    RowBufferEntry[] leftRowBufferEntries  = AstUtil.GetRowBufferEntryReferences(expression.Left);
                    RowBufferEntry[] rightRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Right);

                    if (leftRowBufferEntries.Length == 1 && rightRowBufferEntries.Length == 1)
                    {
                        RowBufferEntry leftRowBufferEntry  = leftRowBufferEntries[0];
                        RowBufferEntry rightRowBufferEntry = rightRowBufferEntries[0];
                        bool           leftIsOuter         = IsOuterReference(leftRowBufferEntry);
                        bool           rightIsOuter        = IsOuterReference(rightRowBufferEntry);

                        if (leftRowBufferEntry != rightRowBufferEntry && leftIsOuter ^ rightIsOuter)
                        {
                            // Both expressions depend on extactly one row buffer entry but
                            // they are not refering to the same row buffer entry and
                            // only one is an outer reference.

                            SpoolExpression spoolExpression = new SpoolExpression();
                            if (leftIsOuter)
                            {
                                spoolExpression.IndexExpression = expression.Right;
                                spoolExpression.ProbeExpression = expression.Left;
                            }
                            else
                            {
                                spoolExpression.IndexExpression = expression.Left;
                                spoolExpression.ProbeExpression = expression.Right;
                            }

                            _spoolExpressions.Add(spoolExpression);
                            return(LiteralExpression.FromBoolean(true));
                        }
                    }
                }

                return(expression);
            }
Esempio n. 25
0
            public override AlgebraNode VisitTableAlgebraNode(TableAlgebraNode node)
            {
                TableRefBinding oldTableRefBinding = node.TableRefBinding;
                TableRefBinding newTableRefBinding = new TableRefBinding(oldTableRefBinding.Scope, oldTableRefBinding.TableBinding, oldTableRefBinding.Name);

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

                for (int i = 0; i < newTableRefBinding.ColumnRefs.Length; i++)
                {
                    definedValues.Add(newTableRefBinding.ColumnRefs[i].ValueDefinition);
                    RowBufferEntry oldRowBufferEntry = oldTableRefBinding.ColumnRefs[i].ValueDefinition.Target;
                    RowBufferEntry newRowBufferEntry = newTableRefBinding.ColumnRefs[i].ValueDefinition.Target;
                    _rowBufferMappings.Add(oldRowBufferEntry, newRowBufferEntry);
                }

                node.TableRefBinding = newTableRefBinding;
                node.DefinedValues   = definedValues.ToArray();

                return(node);
            }
Esempio n. 26
0
		private IComparer[] GetComparersFromExpressionTypes(RowBufferEntry[] rowBufferEntries)
		{
			IComparer[] result = new IComparer[rowBufferEntries.Length];

			for (int i = 0; i < result.Length; i++)
			{
				IComparer customComparer = _metadataContext.Comparers[rowBufferEntries[i].DataType];

				if (customComparer != null)
					result[i] = customComparer;
				else
					result[i] = Comparer.Default;
			}

			return result;
		}
Esempio n. 27
0
		private static RuntimeValueOutput GetDefinedValue(RowBufferEntry[] outputList, RowBufferEntry rowBufferEntry)
		{
			RuntimeValueOutput result = new RuntimeValueOutput();
			result.TargetIndex = Array.IndexOf(outputList, rowBufferEntry);
			return result;
		}
Esempio n. 28
0
		private static IteratorInput[] GetIteratorInput(RowBufferEntry[] allEntries, RowBufferEntry[] neededEntries)
		{
			IteratorInput[] result = new IteratorInput[neededEntries.Length];

			for (int i = 0; i < neededEntries.Length; i++)
			{
				result[i] = new IteratorInput();
				result[i].SourceIndex = Array.IndexOf(allEntries, neededEntries[i]);
			}

			return result;
		}
 public EqualPredicatesExtractor(RowBufferEntry[] leftDefinedEntries, RowBufferEntry[] rightDefinedEntries)
 {
     _leftDefinedEntries = leftDefinedEntries;
     _rightDefinedEntries = rightDefinedEntries;
 }
Esempio n. 30
0
		private static NullScanAlgebraNode CreateNullScan(RowBufferEntry[] outputList)
		{
			NullScanAlgebraNode result = new NullScanAlgebraNode();
			result.OutputList = outputList;
			return result;
		}
Esempio n. 31
0
        private RowBufferEntry CreateProbeColumn()
        {
            if (!ProbingEnabled)
                return null;

            RowBufferEntry probeColumn = new RowBufferEntry(typeof(bool));
            return probeColumn;
        }
Esempio n. 32
0
		private void AddNullRejectedTable(RowBufferEntry rowBufferEntries)
		{
			if (!_nullRejectedRowBufferEntries.Contains(rowBufferEntries))
				_nullRejectedRowBufferEntries.Add(rowBufferEntries);
		}
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            node.Left = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            if (node.Predicate != null &&
                (node.OuterReferences == null || node.OuterReferences.Length == 0) &&
                (
                    node.Op == JoinAlgebraNode.JoinOperator.InnerJoin ||
                    node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin ||
                    node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin ||
                    node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
                )
            {
                RowBufferEntry[] leftDefinedEntries = AstUtil.GetDefinedValueEntries(node.Left);
                RowBufferEntry[] rightDefinedEntries = AstUtil.GetDefinedValueEntries(node.Right);

                EqualPredicatesExtractor equalPredicatesExtractor = new EqualPredicatesExtractor(leftDefinedEntries, rightDefinedEntries);
                ExpressionNode probeResidual = equalPredicatesExtractor.VisitExpression(node.Predicate);
                BinaryExpression[] equalPredicates = equalPredicatesExtractor.GetEqualPredicates();

                if (equalPredicates.Length > 0)
                {
                    BinaryExpression equalPredicate = equalPredicates[0];

                    ExpressionBuilder expressionBuilder = new ExpressionBuilder();
                    expressionBuilder.Push(probeResidual);

                    if (equalPredicates.Length > 1)
                    {
                        for (int i = 1; i < equalPredicates.Length; i++)
                            expressionBuilder.Push(equalPredicates[i]);
                        expressionBuilder.PushNAry(LogicalOperator.And);
                    }

                    probeResidual = expressionBuilder.Pop();
                    if (probeResidual is ConstantExpression)
                        probeResidual = null;

                    AlgebraNode leftInput = node.Left;
                    AlgebraNode rightInput = node.Right;

                    if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin)
                    {
                        node.Op = JoinAlgebraNode.JoinOperator.RightOuterJoin;
                        leftInput = node.Right;
                        rightInput = node.Left;
                        ExpressionNode oldLeft = equalPredicate.Left;
                        equalPredicate.Left = equalPredicate.Right;
                        equalPredicate.Right = oldLeft;
                    }

                    RowBufferEntry leftEntry;
                    RowBufferEntryExpression leftAsRowBufferEntryExpression = equalPredicate.Left as RowBufferEntryExpression;
                    if (leftAsRowBufferEntryExpression != null)
                    {
                        leftEntry = leftAsRowBufferEntryExpression.RowBufferEntry;
                    }
                    else
                    {
                        leftEntry = new RowBufferEntry(equalPredicate.Left.ExpressionType);
                        ComputedValueDefinition definedValue = new ComputedValueDefinition();
                        definedValue.Target = leftEntry;
                        definedValue.Expression = equalPredicate.Left;

                        ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                        computeScalarAlgebraNode.Input = leftInput;
                        computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] {definedValue};
                        leftInput = computeScalarAlgebraNode;
                    }

                    RowBufferEntry rightEntry;
                    RowBufferEntryExpression rightAsRowBufferEntryExpression = equalPredicate.Right as RowBufferEntryExpression;
                    if (rightAsRowBufferEntryExpression != null)
                    {
                        rightEntry = rightAsRowBufferEntryExpression.RowBufferEntry;
                    }
                    else
                    {
                        rightEntry = new RowBufferEntry(equalPredicate.Right.ExpressionType);
                        ComputedValueDefinition definedValue = new ComputedValueDefinition();
                        definedValue.Target = rightEntry;
                        definedValue.Expression = equalPredicate.Right;

                        ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                        computeScalarAlgebraNode.Input = rightInput;
                        computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] {definedValue};
                        rightInput = computeScalarAlgebraNode;
                    }

                    HashMatchAlgebraNode hashMatchAlgebraNode = new HashMatchAlgebraNode();
                    hashMatchAlgebraNode.Op = node.Op;
                    hashMatchAlgebraNode.Left = leftInput;
                    hashMatchAlgebraNode.Right = rightInput;
                    hashMatchAlgebraNode.BuildKeyEntry = leftEntry;
                    hashMatchAlgebraNode.ProbeEntry = rightEntry;
                    hashMatchAlgebraNode.ProbeResidual = probeResidual;
                    return hashMatchAlgebraNode;
                }
            }

            return node;
        }
Esempio n. 34
0
			public BoundRowBufferEntrySet(object[] rowBuffer, RowBufferEntry[] entries)
			{
				RowBuffer = rowBuffer;
				Entries = entries;
			}
Esempio n. 35
0
			public CteColumnMappingFinder(CommonTableBinding commonTableBinding, RowBufferEntry[] spoolBufferEntries)
			{
				_commonTableBinding = commonTableBinding;
				_spoolBufferEntries = spoolBufferEntries;
			}
Esempio n. 36
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);
        }
Esempio n. 37
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));
            }
        }
Esempio n. 38
0
		public static bool DoesNotReference(RowBufferEntry[] rowBufferEntryReferences, RowBufferEntry[] rowBufferEntries)
		{
			foreach (RowBufferEntry rowBufferColumnDependency in rowBufferEntryReferences)
			{
				if (ArrayHelpers.Contains(rowBufferEntries, rowBufferColumnDependency))
					return false;
			}

			return true;
		}
Esempio n. 39
0
		public static bool ExpressionDoesNotReference(ExpressionNode expression, RowBufferEntry[] rowBufferEntries)
		{
			RowBufferEntry[] rowBufferEntryReferences = GetRowBufferEntryReferences(expression);

			return DoesNotReference(rowBufferEntryReferences, rowBufferEntries);
		}
Esempio n. 40
0
		public static bool ExpressionYieldsNullOrFalseIfRowBufferEntryNull(ExpressionNode expressionNode, RowBufferEntry rowBufferEntry)
		{
			NullRejectionChecker checker = new NullRejectionChecker(rowBufferEntry);
			checker.Visit(expressionNode);

			if (checker.ExpressionRejectsNull)
				return true;

			return false;
		}
Esempio n. 41
0
		public NullRejectionChecker(RowBufferEntry rowBufferEntry)
		{
			_rowBufferEntry = rowBufferEntry;
		}
Esempio n. 42
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);
        }
Esempio n. 43
0
        private static ResultAlgebraNode CreateAssertedSubquery(ResultAlgebraNode inputNode)
        {
            if (AstUtil.WillProduceAtMostOneRow(inputNode))
            {
                return(inputNode);
            }

            RowBufferEntry inputEntry = inputNode.OutputList[0];

            AggregatedValueDefinition countDefinedValue = new AggregatedValueDefinition();

            countDefinedValue.Aggregate  = new CountAggregateBinding("COUNT");
            countDefinedValue.Aggregator = countDefinedValue.Aggregate.CreateAggregator(typeof(int));
            countDefinedValue.Argument   = LiteralExpression.FromInt32(0);

            RowBufferEntry countDefinedValueEntry = new RowBufferEntry(countDefinedValue.Aggregator.ReturnType);

            countDefinedValue.Target = countDefinedValueEntry;

            RowBufferEntryExpression anyAggregateArgument = new RowBufferEntryExpression();

            anyAggregateArgument.RowBufferEntry = inputEntry;

            AggregatedValueDefinition anyDefinedValue = new AggregatedValueDefinition();

            anyDefinedValue.Aggregate  = new FirstAggregateBinding("ANY");
            anyDefinedValue.Aggregator = anyDefinedValue.Aggregate.CreateAggregator(inputEntry.DataType);
            anyDefinedValue.Argument   = anyAggregateArgument;

            RowBufferEntry anyDefinedValueEntry = new RowBufferEntry(inputEntry.DataType);

            anyDefinedValue.Target = anyDefinedValueEntry;

            AggregateAlgebraNode aggregateAlgebraNode = new AggregateAlgebraNode();

            aggregateAlgebraNode.Input         = inputNode.Input;
            aggregateAlgebraNode.DefinedValues = new AggregatedValueDefinition[] { countDefinedValue, anyDefinedValue };

            // CASE WHEN SubqueryCount > 1 THEN 0 ELSE NULL END

            ExpressionBuilder expressionBuilder = new ExpressionBuilder();

            expressionBuilder.Push(new RowBufferEntryExpression(countDefinedValueEntry));
            expressionBuilder.Push(LiteralExpression.FromInt32(1));
            expressionBuilder.PushBinary(BinaryOperator.Greater);
            ExpressionNode whenExpression = expressionBuilder.Pop();
            ExpressionNode thenExpression = LiteralExpression.FromInt32(0);

            CaseExpression caseExpression = new CaseExpression();

            caseExpression.WhenExpressions = new ExpressionNode[] { whenExpression };
            caseExpression.ThenExpressions = new ExpressionNode[] { thenExpression };

            expressionBuilder.Push(caseExpression);
            ExpressionNode predicate = expressionBuilder.Pop();

            AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode();

            assertAlgebraNode.Input         = aggregateAlgebraNode;
            assertAlgebraNode.Predicate     = predicate;
            assertAlgebraNode.AssertionType = AssertionType.MaxOneRow;

            ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode();

            resultAlgebraNode.Input       = assertAlgebraNode;
            resultAlgebraNode.OutputList  = new RowBufferEntry[] { anyDefinedValueEntry };
            resultAlgebraNode.ColumnNames = inputNode.ColumnNames;

            return(resultAlgebraNode);
        }
Esempio n. 44
0
 public RowBufferEntryExpression(RowBufferEntry rowBufferEntry)
 {
     _rowBufferEntry = rowBufferEntry;
 }
Esempio n. 45
0
        private static ResultAlgebraNode CreateAssertedSubquery(ResultAlgebraNode inputNode)
        {
            if (AstUtil.WillProduceAtMostOneRow(inputNode))
                return inputNode;

            RowBufferEntry inputEntry = inputNode.OutputList[0];

            AggregatedValueDefinition countDefinedValue = new AggregatedValueDefinition();
            countDefinedValue.Aggregate = new CountAggregateBinding("COUNT");
            countDefinedValue.Aggregator = countDefinedValue.Aggregate.CreateAggregator(typeof(int));
            countDefinedValue.Argument = LiteralExpression.FromInt32(0);

            RowBufferEntry countDefinedValueEntry = new RowBufferEntry(countDefinedValue.Aggregator.ReturnType);
            countDefinedValue.Target = countDefinedValueEntry;

            RowBufferEntryExpression anyAggregateArgument = new RowBufferEntryExpression();
            anyAggregateArgument.RowBufferEntry = inputEntry;

            AggregatedValueDefinition anyDefinedValue = new AggregatedValueDefinition();
            anyDefinedValue.Aggregate = new FirstAggregateBinding("ANY");
            anyDefinedValue.Aggregator = anyDefinedValue.Aggregate.CreateAggregator(inputEntry.DataType);
            anyDefinedValue.Argument = anyAggregateArgument;

            RowBufferEntry anyDefinedValueEntry = new RowBufferEntry(inputEntry.DataType);
            anyDefinedValue.Target = anyDefinedValueEntry;

            AggregateAlgebraNode aggregateAlgebraNode = new AggregateAlgebraNode();
            aggregateAlgebraNode.Input = inputNode.Input;
            aggregateAlgebraNode.DefinedValues = new AggregatedValueDefinition[] { countDefinedValue, anyDefinedValue };

            // CASE WHEN SubqueryCount > 1 THEN 0 ELSE NULL END

            ExpressionBuilder expressionBuilder = new ExpressionBuilder();
            expressionBuilder.Push(new RowBufferEntryExpression(countDefinedValueEntry));
            expressionBuilder.Push(LiteralExpression.FromInt32(1));
            expressionBuilder.PushBinary(BinaryOperator.Greater);
            ExpressionNode whenExpression = expressionBuilder.Pop();
            ExpressionNode thenExpression = LiteralExpression.FromInt32(0);

            CaseExpression caseExpression = new CaseExpression();
            caseExpression.WhenExpressions = new ExpressionNode[] { whenExpression };
            caseExpression.ThenExpressions = new ExpressionNode[] { thenExpression };

            expressionBuilder.Push(caseExpression);
            ExpressionNode predicate = expressionBuilder.Pop();

            AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode();
            assertAlgebraNode.Input = aggregateAlgebraNode;
            assertAlgebraNode.Predicate = predicate;
            assertAlgebraNode.AssertionType = AssertionType.MaxOneRow;

            ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode();
            resultAlgebraNode.Input = assertAlgebraNode;
            resultAlgebraNode.OutputList = new RowBufferEntry[] { anyDefinedValueEntry };
            resultAlgebraNode.ColumnNames = inputNode.ColumnNames;

            return resultAlgebraNode;
        }
Esempio n. 46
0
 private bool IsNeeded(RowBufferEntry rowBufferColumn)
 {
     return(_neededRowBufferColumns.Contains(rowBufferColumn));
 }
Esempio n. 47
0
        private ExpressionNode CreateProbeColumnRef(RowBufferEntry probeColumn)
        {
            if (!ProbingEnabled)
                return LiteralExpression.FromBoolean(true);

            RowBufferEntryExpression probeColumnRef = new RowBufferEntryExpression(probeColumn);
            return probeColumnRef;
        }
Esempio n. 48
0
 private void ReplaceRowBufferEntries(RowBufferEntry[] rowBufferEntries)
 {
     for (int i = 0; i < rowBufferEntries.Length; i++)
         rowBufferEntries[i] = ReplaceRowBufferEntry(rowBufferEntries[i]);
 }
Esempio n. 49
0
 private static void WriteRowBufferEntry(PropertyListBuilder builder, string groupName, RowBufferEntry rowBufferColumn)
 {
     builder.Begin(groupName);
     builder.SetGroupValue(rowBufferColumn.Name);
     WriteRowBufferEntry(builder, rowBufferColumn);
     builder.End();
 }
Esempio n. 50
0
 public NullRejectionChecker(RowBufferEntry rowBufferEntry)
 {
     _rowBufferEntry = rowBufferEntry;
 }
 public RowBufferEntryExpression(RowBufferEntry rowBufferEntry)
 {
     _rowBufferEntry = rowBufferEntry;
 }
Esempio n. 52
0
        private RowBufferEntry ReplaceRowBufferEntry(RowBufferEntry rowBufferEntry)
        {
            RowBufferEntry replacementEntry;
            if (_inliningDictionary.TryGetValue(rowBufferEntry, out replacementEntry))
                return replacementEntry;

            return rowBufferEntry;
        }
Esempio n. 53
0
		private static IteratorOutput[] GetIteratorOutput(int offset, RowBufferEntry[] allEntries, RowBufferEntry[] neededEntries)
		{
			List<IteratorOutput> result = new List<IteratorOutput>(neededEntries.Length);

			for (int i = 0; i < allEntries.Length; i++)
			{
				if (ArrayHelpers.Contains(neededEntries, allEntries[i]))
				{
					IteratorOutput iteratorOutput = new IteratorOutput();
					iteratorOutput.SourceIndex = i;
					iteratorOutput.TargetIndex = offset + result.Count;
					result.Add(iteratorOutput);
				}
			}

			return result.ToArray();
		}
Esempio n. 54
0
        public static bool ExpressionYieldsNullOrFalseIfRowBufferEntryNull(ExpressionNode expressionNode, RowBufferEntry rowBufferEntry)
        {
            NullRejectionChecker checker = new NullRejectionChecker(rowBufferEntry);

            checker.Visit(expressionNode);

            if (checker.ExpressionRejectsNull)
            {
                return(true);
            }

            return(false);
        }
Esempio n. 55
0
		private RuntimeAggregateValueOutput[] GetDefinedValues(RowBufferEntry[] outputList, AggregatedValueDefinition[] definedValues, params BoundRowBufferEntrySet[] boundRowBufferEntrySets)
		{
			RuntimeAggregateValueOutput[] result = new RuntimeAggregateValueOutput[definedValues.Length];

			for (int i = 0; i < definedValues.Length; i++)
			{
				RuntimeAggregateValueOutput definedValue = new RuntimeAggregateValueOutput();
				definedValue.Aggregator = definedValues[i].Aggregator;
				definedValue.Argument = CreateRuntimeExpression(definedValues[i].Argument, boundRowBufferEntrySets);
				definedValue.TargetIndex = Array.IndexOf(outputList, definedValues[i].Target);
				result[i] = definedValue;
			}

			return result;
		}
Esempio n. 56
0
            private bool IsOuterReference(RowBufferEntry entry)
            {
                foreach (RowBufferEntry[] outerReferences in _outerReferences)
                {
                    if (ArrayHelpers.Contains(outerReferences, entry))
                        return true;
                }

                return false;
            }
Esempio n. 57
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);
			}
		}
Esempio n. 58
0
        public override AlgebraNode VisitFilterAlgebraNode(FilterAlgebraNode node)
        {
            node.Input = VisitAlgebraNode(node.Input);

            ExpressionNode           originalPredicate        = (ExpressionNode)node.Predicate.Clone();
            SpoolExpressionExtractor spoolExpressionExtractor = new SpoolExpressionExtractor(_outerReferences);

            // HACK: This hack ensures that TRUE literals introduced by SpoolExpressionExtractor are removed.
            node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, spoolExpressionExtractor.VisitExpression(node.Predicate));
            SpoolExpression[] spoolExpressions = spoolExpressionExtractor.GetSpoolExpressions();

            // Now we must check that the remaining filter incl. input to the filter don't reference any other
            // outer reference.

            bool remainingFilterHasDependenciesToOuterReferences = CheckIfNodeHasDependenciesToOuterReferences(node);

            if (remainingFilterHasDependenciesToOuterReferences)
            {
                // OK; we cannot insert a spool operation here. Undo the expression replacement.
                node.Predicate = originalPredicate;
            }
            else if (spoolExpressions.Length > 0)
            {
                SpoolExpression spoolExpression = spoolExpressions[0];

                AlgebraNode currentInput;

                if (node.Predicate is ConstantExpression)
                {
                    currentInput = node.Input;
                }
                else
                {
                    currentInput = node;
                }

                RowBufferEntry           indexEntry;
                RowBufferEntryExpression indexExpressionAsRowBufferEntryExpression = spoolExpression.IndexExpression as RowBufferEntryExpression;

                if (indexExpressionAsRowBufferEntryExpression != null)
                {
                    indexEntry = indexExpressionAsRowBufferEntryExpression.RowBufferEntry;
                }
                else
                {
                    indexEntry = new RowBufferEntry(spoolExpression.IndexExpression.ExpressionType);
                    ComputedValueDefinition definedValue = new ComputedValueDefinition();
                    definedValue.Target     = indexEntry;
                    definedValue.Expression = spoolExpression.IndexExpression;

                    ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
                    computeScalarAlgebraNode.Input         = currentInput;
                    computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { definedValue };
                    currentInput = computeScalarAlgebraNode;
                }

                IndexSpoolAlgebraNode indexSpoolAlgebraNode = new IndexSpoolAlgebraNode();
                indexSpoolAlgebraNode.Input           = currentInput;
                indexSpoolAlgebraNode.IndexEntry      = indexEntry;
                indexSpoolAlgebraNode.ProbeExpression = spoolExpression.ProbeExpression;
                return(indexSpoolAlgebraNode);
            }

            return(node);
        }
Esempio n. 59
0
        private static void CreateBufferedValue(ExpressionNode expression, ICollection<ComputedValueDefinition> computedColumnList, ICollection<RowBufferEntry> columnList, IEnumerable<ComputedValueDefinition> alreadyComputedBufferedValues)
        {
            if (alreadyComputedBufferedValues != null)
                expression = ReplaceAlreadyComputedSubsequences(expression, alreadyComputedBufferedValues);

            foreach (ComputedValueDefinition computedBufferedValue in computedColumnList)
            {
                if (expression.IsStructuralEqualTo(computedBufferedValue.Expression))
                {
                    columnList.Add(computedBufferedValue.Target);
                    return;
                }
            }

            RowBufferEntryExpression rowBufferExpression = expression as RowBufferEntryExpression;
            if (rowBufferExpression != null)
            {
                columnList.Add(rowBufferExpression.RowBufferEntry);
            }
            else
            {
                RowBufferEntry rowBufferEntry = new RowBufferEntry(expression.ExpressionType);
                columnList.Add(rowBufferEntry);

                ComputedValueDefinition computedValue = new ComputedValueDefinition();
                computedValue.Target = rowBufferEntry;
                computedValue.Expression = expression;
                computedColumnList.Add(computedValue);
            }
        }
Esempio n. 60
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));
            }
        }