コード例 #1
0
ファイル: SelectQuery.cs プロジェクト: chenzuo/nquery
		public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements)
		{
			SelectQuery result = new SelectQuery();
			result.IsDistinct = _isDistinct;
			
			if (_topClause != null)
				result.TopClause = (TopClause)_topClause.Clone(alreadyClonedElements);

			result.SelectColumns = ArrayHelpers.CreateDeepCopyOfAstElementArray(_selectColumns, alreadyClonedElements);

			if (_tableReferences != null)
				result.TableReferences = (TableReference)_tableReferences.Clone(alreadyClonedElements);
			
			if (_whereClause != null)
				result.WhereClause = (ExpressionNode)_whereClause.Clone(alreadyClonedElements);
			
			if (_groupByColumns != null)
				result.GroupByColumns = ArrayHelpers.CreateDeepCopyOfAstElementArray(_groupByColumns, alreadyClonedElements);
			
			if (_orderByColumns != null)
				result.OrderByColumns = ArrayHelpers.CreateDeepCopyOfAstElementArray(_orderByColumns, alreadyClonedElements);

			result.AggregateDependencies = ArrayHelpers.CreateDeepCopyOfAstElementArray(_aggregateDependencies, alreadyClonedElements);
			result.ColumnDependencies =  ArrayHelpers.Clone(_columnDependencies);

			return result;
		}
コード例 #2
0
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			base.VisitSelectQuery(query);

			RowBufferCalculator rowBufferCalculator = new RowBufferCalculator(query);
			rowBufferCalculator.Calculate();
			query.RowBufferCalculator = rowBufferCalculator;

			return query;
		}
コード例 #3
0
ファイル: MetaInfoFinder.cs プロジェクト: chenzuo/nquery
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			if (_nestingLevel == 0)
				return base.VisitSelectQuery(query);
			
			if (_nestingLevel > 0)
			{
                _queryScopeStack.Push(query.QueryScope);
				base.VisitSelectQuery(query);
                _queryScopeStack.Pop();
			}
			
			return query;
		}
コード例 #4
0
ファイル: RowBufferCalculator.cs プロジェクト: chenzuo/nquery
 public RowBufferCalculator(SelectQuery selectQuery)
 {
     _selectQuery = selectQuery;
 }
コード例 #5
0
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			if (query.IsDistinct)
				_containsDisctinct = true;
			if (query.TopClause != null)
				_containsTop = true;
			if (query.GroupByColumns != null)
				_containsGroupByHavingOrAggregate = true;

			return base.VisitSelectQuery(query);
		}
コード例 #6
0
ファイル: Comparer.cs プロジェクト: chenzuo/nquery
		private static bool VisitSelectQuery(SelectQuery node1, SelectQuery node2)
		{
			if (node2 == null)
				return false;

			if (node1.IsAggregated != node2.IsAggregated ||
				node1.IsDistinct != node2.IsDistinct ||
				node1.SelectColumns.Length != node2.SelectColumns.Length ||
				(node1.TableReferences == null) != (node2.TableReferences == null) ||
				(node1.TopClause == null) != (node2.TopClause == null) ||
				(node1.WhereClause == null) != (node2.WhereClause == null) ||
				(node1.GroupByColumns == null) != (node2.GroupByColumns == null) ||
				(node1.OrderByColumns == null) != (node2.OrderByColumns == null))
				return false;

			if (node1.TopClause != null)
				if (node1.TopClause.Value != node2.TopClause.Value)
					return false;

			for (int i = 0; i < node1.SelectColumns.Length; i++)
			{
				if (node1.SelectColumns[i].IsAsterisk != node2.SelectColumns[i].IsAsterisk ||
					node1.SelectColumns[i].Alias != node2.SelectColumns[i].Alias ||
					(node1.SelectColumns[i].Expression == null) != (node2.SelectColumns[i].Expression == null))
					return false;

				if (node1.SelectColumns[i].Expression != null)
					if (!Visit(node1.SelectColumns[i].Expression, node2.SelectColumns[i].Expression))
						return false;
			}

			if (node1.TableReferences != null)
				if (!Visit(node1.TableReferences, node2.TableReferences))
					return false;

			if (node1.WhereClause != null)
				if (!Visit(node1.WhereClause, node2.WhereClause))
					return false;

			if (node1.HavingClause != null)
				if (!Visit(node1.HavingClause, node2.HavingClause))
					return false;

			if (node1.GroupByColumns != null)
			{
				if (node1.GroupByColumns.Length != node2.GroupByColumns.Length)
					return false;

				for (int i = 0; i < node1.GroupByColumns.Length; i++)
					if (!Visit(node1.GroupByColumns[i], node2.GroupByColumns[i]))
						return false;
			}

			if (node1.OrderByColumns != null)
			{
				for (int i = 0; i < node1.OrderByColumns.Length; i++)
				{
					if (node1.OrderByColumns[i].SortOrder != node2.OrderByColumns[i].SortOrder)
						return false;

					if (!Visit(node1.OrderByColumns[i].Expression, node2.OrderByColumns[i].Expression))
						return false;
				}
			}

			return true;
		}
コード例 #7
0
ファイル: SourceGenerator.cs プロジェクト: chenzuo/nquery
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			_writer.Write(SELECT);
			_writer.Indent += SELECT_INDENT;

			if (!query.IsDistinct && query.TopClause == null)
			{
				_writer.Write(" ");
			}
			else
			{
				// DISTINCT

				if (query.IsDistinct)
					_writer.Write(" DISTINCT");

				// TOP

				if (query.TopClause != null)
				{
					_writer.Write(" TOP ");
					_writer.WriteLiteral(query.TopClause.Value);
				}

				_writer.WriteLine();
			}

			// Columns

			bool isFirst = true;
			foreach (SelectColumn columnSource in query.SelectColumns)
			{
				if (isFirst)
				{
					isFirst = false;
				}
				else
				{
					_writer.Write(",");
					_writer.WriteLine();
				}

				if (columnSource.IsAsterisk)
				{
					if (columnSource.Alias != null)
					{
						_writer.Write(columnSource.Alias.ToString());
						_writer.Write(".");
					}

					_writer.Write("*");
				}
				else
				{
					Visit(columnSource.Expression);

					if (columnSource.Alias != null)
					{
						_writer.Write(" AS ");
						_writer.Write(columnSource.Alias.ToString());
					}
				}
			}

			_writer.Indent -= SELECT_INDENT;

			// FROM

			if (query.TableReferences != null)
			{
				_writer.WriteLine();
				_writer.Write(FROM);
				_writer.Write(" ");
				_writer.Indent += SELECT_INDENT;
				Visit(query.TableReferences);
				_writer.Indent -= SELECT_INDENT;
			}

			// WHERE

			if (query.WhereClause != null)
			{
				_writer.WriteLine();
				_writer.Write(WHERE);
				_writer.Write(" ");
				_writer.Indent += SELECT_INDENT;
				Visit(query.WhereClause);
				_writer.Indent -= SELECT_INDENT;
			}

			// GROUP BY

			if (query.GroupByColumns != null)
			{
				_writer.WriteLine();
				_writer.Write(GROUPBY);
				_writer.Write(" ");
				_writer.Indent += SELECT_INDENT;

				isFirst = true;
				foreach (ExpressionNode groupyByExpression in query.GroupByColumns)
				{
					if (isFirst)
					{
						isFirst = false;
					}
					else
					{
						_writer.Write(",");
						_writer.WriteLine();
					}

					Visit(groupyByExpression);
				}

				_writer.Indent -= SELECT_INDENT;
			}

			// HAVING

			if (query.HavingClause != null)
			{
				_writer.WriteLine();
				_writer.Write(HAVING);
				_writer.Write(" ");
				_writer.Indent += SELECT_INDENT;
				Visit(query.HavingClause);
				_writer.Indent -= SELECT_INDENT;
			}

			return query;
		}
コード例 #8
0
ファイル: Parser.cs プロジェクト: chenzuo/nquery
        private QueryNode ParseSelectQuery()
        {
            if (_token.Id == TokenId.LeftParentheses)
            {
                NextToken();
                QueryNode result = ParseQuery();
                Match(TokenId.RightParentheses);
                return result;
            }

            if (!Match(TokenId.SELECT))
                return null;

            SelectQuery selectQuery = new SelectQuery();

            // DISTINCT

            if (_token.Id == TokenId.DISTINCT)
            {
                selectQuery.IsDistinct = true;
                NextToken();
            }

            // TOP

            if (_token.Id == TokenId.TOP)
            {
                NextToken();

                TopClause topClause = new TopClause();
                topClause.Value = (int)ParseInteger();

                if (_token.Id == TokenId.WITH)
                {
                    NextToken();
                    Match(TokenId.TIES);
                    topClause.WithTies = true;
                }
                selectQuery.TopClause = topClause;
            }

            // SelectColumns

            selectQuery.SelectColumns = ParseColumnSources();

            // FROM

            if (_token.Id == TokenId.FROM)
            {
                NextToken();
                selectQuery.TableReferences = ParseTableReferences();
            }

            // WHERE

            if (_token.Id == TokenId.WHERE)
            {
                NextToken();
                selectQuery.WhereClause = ParseExpression();
            }

            // GROUP BY

            if (_token.Id == TokenId.GROUP)
            {
                NextToken();
                Match(TokenId.BY);
                selectQuery.GroupByColumns = ParseExpressions();
            }

            // HAVING

            if (_token.Id == TokenId.HAVING)
            {
                NextToken();
                selectQuery.HavingClause = ParseExpression();
            }

            return selectQuery;
        }
コード例 #9
0
ファイル: StandardVisitor.cs プロジェクト: chenzuo/nquery
		public virtual QueryNode VisitSelectQuery(SelectQuery query)
		{
			// Visit all column expressions

			for (int i = 0; i < query.SelectColumns.Length; i++)
			{
				if (query.SelectColumns[i].Expression != null)
					query.SelectColumns[i].Expression = VisitExpression(query.SelectColumns[i].Expression);
			}

			// Visit FROM table references

			if (query.TableReferences != null)
				query.TableReferences = VisitTableReference(query.TableReferences);

			// Visit WHERE expression

			if (query.WhereClause != null)
				query.WhereClause = VisitExpression(query.WhereClause);

			// Visit GROUP BY clause

			if (query.GroupByColumns != null)
			{
				for (int i = 0; i < query.GroupByColumns.Length; i++)
					query.GroupByColumns[i] = VisitExpression(query.GroupByColumns[i]);
			}

			if (query.HavingClause != null)
				query.HavingClause = VisitExpression(query.HavingClause);

			// Visit ORDER BY expressions

			if (query.OrderByColumns != null)
			{
				for (int i = 0; i < query.OrderByColumns.Length; i++)
					query.OrderByColumns[i].Expression = VisitExpression(query.OrderByColumns[i].Expression);
			}

			return query;
		}
コード例 #10
0
ファイル: Resolver.cs プロジェクト: chenzuo/nquery
        public override QueryNode VisitSelectQuery(SelectQuery query)
        {
            query.QueryScope = PushNewScope(query.QueryScope);
            try
            {
                if (query.TableReferences != null)
                {
                    // Declare all tables

                    TableReferenceDeclarationFinder tableReferenceDeclarationFinder = new TableReferenceDeclarationFinder();
                    tableReferenceDeclarationFinder.Visit(query.TableReferences);

                    NamedTableReference[] namedTableReferences = tableReferenceDeclarationFinder.GetNamedTableReferences();
                    DerivedTableReference[] derivedTableReferences = tableReferenceDeclarationFinder.GetDerivedTableReferences();

                    foreach (NamedTableReference namedTableReference in namedTableReferences)
                    {
                        TableBinding tableBinding = ResolveTable(namedTableReference.TableNameSourceRange, namedTableReference.TableName);

                        if (tableBinding == null)
                        {
                            ErrorReporter.UndeclaredTable(namedTableReference.TableNameSourceRange, namedTableReference.TableName);
                        }
                        else
                        {
                            Identifier tableReferenceIdentifer;

                            if (namedTableReference.CorrelationName == null)
                                tableReferenceIdentifer = Identifier.CreateVerbatim(tableBinding.Name);
                            else
                                tableReferenceIdentifer = namedTableReference.CorrelationName;

                            TableRefBinding existingTableRef = ResolveTableRef(SourceRange.None, tableReferenceIdentifer);

                            if (existingTableRef != null && existingTableRef.Scope == query.QueryScope)
                                ErrorReporter.DuplicateTableRefInFrom(tableReferenceIdentifer);
                            else
                                namedTableReference.TableRefBinding = CurrentScope.DeclareTableRef(tableBinding, tableReferenceIdentifer);
                        }
                    }

                    foreach (DerivedTableReference derivedTableReference in derivedTableReferences)
                    {
                        derivedTableReference.Query = VisitQuery(derivedTableReference.Query);

                        // Make sure we are only declaring derived tables that have aliases for all expressions.
                        SelectColumn[] selectColumns = derivedTableReference.Query.GetColumns();
                        for (int i = 0; i < selectColumns.Length; i++)
                        {
                            if (selectColumns[i].Alias == null)
                                ErrorReporter.NoColumnAliasSpecified(derivedTableReference.CorrelationNameSourceRange, i, derivedTableReference.CorrelationName);
                        }

                        if (!ErrorReporter.ErrorsSeen)
                        {
                            TableRefBinding existingTableRef = ResolveTableRef(SourceRange.None, derivedTableReference.CorrelationName);

                            if (existingTableRef != null && existingTableRef.Scope == query.QueryScope)
                                ErrorReporter.DuplicateTableRefInFrom(derivedTableReference.CorrelationName);
                            else
                            {
                                DerivedTableBinding derivedTableBinding = new DerivedTableBinding(derivedTableReference.CorrelationName.Text, derivedTableReference.Query);
                                derivedTableReference.DerivedTableBinding = query.QueryScope.DeclareTableRef(derivedTableBinding, derivedTableReference.CorrelationName);
                            }
                        }
                    }

                    // If we could not declare all tables, we stop resolving this query.
                    if (ErrorReporter.ErrorsSeen)
                        return query;

                    // Resolve joins

                    query.TableReferences = VisitTableReference(query.TableReferences);
                }

                // Ensure that we tables specified if using the asterisk.

                if (query.TableReferences == null)
                {
                    foreach (SelectColumn column in query.SelectColumns)
                    {
                        if (column.IsAsterisk)
                            ErrorReporter.MustSpecifyTableToSelectFrom();
                    }
                }

                // If we could not resolve all tables or there are duplicates
                // we must stop here.

                if (ErrorReporter.ErrorsSeen)
                    return query;

                // Expand all * and <alias>.* columns with the corresponding columns.
                //
                // Build a list of all column sources to replace the query.SelectColumns property.

                List<SelectColumn> columnSources = new List<SelectColumn>();

                foreach (SelectColumn columnSource in query.SelectColumns)
                {
                    if (!columnSource.IsAsterisk)
                    {
                        // Nothing to expand, just add the column source
                        // to the list.
                        columnSources.Add(columnSource);
                    }
                    else
                    {
                        // Expand the asterisk.

                        if (columnSource.Alias == null)
                        {
                            // No alias, expand the asterisk to all columns
                            // of all tables.

                            foreach (TableRefBinding tableRefBinding in CurrentScope.GetAllTableRefBindings())
                            {
                                foreach (ColumnBinding columnBinding in tableRefBinding.TableBinding.Columns)
                                {
                                    ColumnRefBinding columnRefBinding = CurrentScope.GetColumnRef(tableRefBinding, columnBinding);
                                    columnSources.Add(new SelectColumn(new ColumnExpression(columnRefBinding), null));
                                }
                            }
                        }
                        else
                        {
                            // Resolve the alias of the column to a table and just
                            // expand the asterisk to the columns of this table.

                            TableRefBinding tableRefBinding = ResolveTableRef(SourceRange.None, columnSource.Alias);

                            if (tableRefBinding == null)
                            {
                                ErrorReporter.UndeclaredTable(SourceRange.None, columnSource.Alias);
                            }
                            else
                            {
                                foreach (ColumnBinding columnDefinition in tableRefBinding.TableBinding.Columns)
                                {
                                    ColumnRefBinding columnRefBinding = CurrentScope.GetColumnRef(tableRefBinding, columnDefinition);
                                    columnSources.Add(new SelectColumn(new ColumnExpression(columnRefBinding), null));
                                }
                            }
                        }
                    }
                }

                // Now we have expanded all asterisks so we can replace the query.SelectColumns
                // property with the expanded list.

                query.SelectColumns = columnSources.ToArray();

                // Resolve
                // - all column selection expressions
                // - WHERE clause,
                // - GROUP BY clause,
                // - HAVING clause
                // - ORDER BY clause.

                for (int i = 0; i < query.SelectColumns.Length; i++)
                    query.SelectColumns[i].Expression = VisitExpression(query.SelectColumns[i].Expression);

                if (query.WhereClause != null)
                    query.WhereClause = VisitExpression(query.WhereClause);

                if (query.GroupByColumns != null)
                {
                    for (int i = 0; i < query.GroupByColumns.Length; i++)
                        query.GroupByColumns[i] = VisitExpression(query.GroupByColumns[i]);
                }

                if (query.HavingClause != null)
                    query.HavingClause = VisitExpression(query.HavingClause);

                if (query.OrderByColumns != null)
                    ResolveOrderBy(query.SelectColumns, query.OrderByColumns);

                // Infer column aliases for the following three expressions:
                //
                // - ColumnExpression
                // - PropertyExpression
                // - NamedConstantExpression
                //
                // In regular SQL only the first one is possible.

                foreach (SelectColumn columnSource in query.SelectColumns)
                {
                    if (columnSource.Alias == null)
                    {
                        ColumnExpression exprAsColumnExpression = columnSource.Expression as ColumnExpression;
                        PropertyAccessExpression exprAsPropertyAccessExpression = columnSource.Expression as PropertyAccessExpression;
                        NamedConstantExpression exprAsNamedConstant = columnSource.Expression as NamedConstantExpression;

                        if (exprAsColumnExpression != null)
                            columnSource.Alias = Identifier.CreateVerbatim(exprAsColumnExpression.Column.Name);
                        else if (exprAsPropertyAccessExpression != null)
                            columnSource.Alias = exprAsPropertyAccessExpression.Name;
                        else if (exprAsNamedConstant != null)
                            columnSource.Alias = Identifier.CreateVerbatim(exprAsNamedConstant.Constant.Name);
                    }
                }

                // Ensure WHERE clause is a boolean expression

                if (query.WhereClause != null)
                {
                    if (query.WhereClause.ExpressionType == typeof(DBNull))
                    {
                        // This means the user entered something like SELECT ... WHERE null = null
                        //
                        // NOTE: We cannot test on literals since constant folding will be applied
                        //       later.

                        query.WhereClause = LiteralExpression.FromBoolean(false);
                    }
                    else if (query.WhereClause.ExpressionType != null &&
                             query.WhereClause.ExpressionType != typeof(bool))
                    {
                        ErrorReporter.WhereClauseMustEvaluateToBool();
                    }
                }

                // Ensure HAVING clause is boolean expression

                if (query.HavingClause != null)
                {
                    if (query.HavingClause.ExpressionType == typeof(DBNull))
                    {
                        // See WHERE clause handler above.

                        query.HavingClause = LiteralExpression.FromBoolean(false);
                    }
                    else if (query.HavingClause.ExpressionType != null &&
                             query.HavingClause.ExpressionType != typeof(bool))
                    {
                        ErrorReporter.HavingClauseMustEvaluateToBool();
                    }
                }

                MetaInfo metaInfo = AstUtil.GetMetaInfo(query);
                query.ColumnDependencies = metaInfo.ColumnDependencies;

                return query;
            }
            finally
            {
                PopScope();
            }
        }
コード例 #11
0
ファイル: ConstantFolder.cs プロジェクト: chenzuo/nquery
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			base.VisitSelectQuery(query);

            if (query.OrderByColumns != null)
            {
                foreach (OrderByColumn orderByColumn in query.OrderByColumns)
                {
                    if (orderByColumn.Expression is ConstantExpression)
                        _errorReporter.ConstantExpressionInOrderBy();
                }
            }
		    			
			return query;
		}
コード例 #12
0
ファイル: Validator.cs プロジェクト: chenzuo/nquery
        public override QueryNode VisitSelectQuery(SelectQuery query)
        {
            PushQueryScope(query.QueryScope);

            // Validate all embedded AST entries that need to check a query context.

            _queryNestingLevel++;
            QueryNode result = base.VisitSelectQuery(query);
            _queryNestingLevel--;

            // Validate DISTINCT

            if (query.IsDistinct)
            {
                // Ensure that all column sources are datatypes that are comparable.

                foreach (SelectColumn columnSource in query.SelectColumns)
                {
                    if (!CheckIfTypeIsComparable(columnSource.Expression.ExpressionType))
                        _errorReporter.InvalidDataTypeInSelectDistinct(columnSource.Expression.ExpressionType);
                }
            }

            // Validate TOP

            if (query.TopClause != null)
            {
                if (query.TopClause.WithTies && query.OrderByColumns == null)
                    _errorReporter.TopWithTiesRequiresOrderBy();
            }

            // Ensure that all ORDER BY datatypes are comparable.

            if (query.OrderByColumns != null)
                ValidateOrderByClause(query.OrderByColumns);

            // Ensure that if both DISTINCT and ORDER BY are presents all expressions in ORDER BY are also part in SELECT.

            if (query.IsDistinct && query.OrderByColumns != null)
            {
                bool allColumnsAreInInput = GetAllColumnsAreInInput(query.SelectColumns, query.OrderByColumns);
                if (!allColumnsAreInInput)
                    _errorReporter.OrderByItemsMustBeInSelectListIfDistinctSpecified();
            }

            // Validate GROUP BY and aggregation-only queries.

            if (query.GroupByColumns == null)
            {
                if (query.IsAggregated || query.HavingClause != null)
                {
                    // No grouping applied but at least one aggregation function present. That
                    // means we have an aggregation-only query.
                    //
                    // Check that all expressions in SELECT are either aggregated or do not
                    // reference any column.

                    foreach (SelectColumn columnSource in query.SelectColumns)
                    {
                        foreach (ColumnRefBinding referencedColumn in AstUtil.GetUngroupedAndUnaggregatedColumns(null, columnSource.Expression))
                        {
                            if (referencedColumn.Scope == query.QueryScope)
                            {
                                // The column is not an outer reference so this is an error.
                                _errorReporter.SelectExpressionNotAggregatedAndNoGroupBy(referencedColumn);
                            }
                        }
                    }

                    // Check that all expressions in HAVING are either aggregated or do not
                    // reference any column.

                    if (query.HavingClause != null)
                    {
                        foreach (ColumnRefBinding referencedColumn in AstUtil.GetUngroupedAndUnaggregatedColumns(null, query.HavingClause))
                        {
                            if (referencedColumn.Scope == query.QueryScope)
                            {
                                // The column is not an outer reference so this is an error.
                                _errorReporter.HavingExpressionNotAggregatedOrGrouped(referencedColumn);
                            }
                        }
                    }

                    // Check that all expressions in ORDER BY are either aggregated or do not
                    // reference any column.

                    if (query.OrderByColumns != null)
                    {
                        foreach (OrderByColumn orderByColumn in query.OrderByColumns)
                        {
                            foreach (ColumnRefBinding referencedColumn in AstUtil.GetUngroupedAndUnaggregatedColumns(null, orderByColumn.Expression))
                            {
                                if (referencedColumn.Scope == query.QueryScope)
                                {
                                    // The column is not an outer reference so this is an error.
                                    _errorReporter.OrderByExpressionNotAggregatedAndNoGroupBy(referencedColumn);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // Grouped query:
                //
                // 1. All expression in GROUP BY must have a datatype that is comparable.
                //
                // 2. All expressions in GROUP BY must not be aggregated
                //
                // 3. All expressions in SELECT, ORDER BY, and HAVING must be aggregated, grouped or must not reference
                //    columns.

                // Check that all GROUP BY expressions are not aggregated.

                foreach (ExpressionNode groupExpression in query.GroupByColumns)
                {
                    if (!CheckIfTypeIsComparable(groupExpression.ExpressionType))
                        _errorReporter.InvalidDataTypeInGroupBy(groupExpression.ExpressionType);

                    MetaInfo metaInfo = AstUtil.GetMetaInfo(groupExpression);
                    if (metaInfo.ColumnDependencies.Length == 0)
                        _errorReporter.GroupByItemDoesNotReferenceAnyColumns();
                }

                // Check that all expressions in SELECT are either part of the GROUP BY or are referencing only those
                // columns that are part of the GROUP BY.

                foreach (SelectColumn columnSource in query.SelectColumns)
                {
                    foreach (ColumnRefBinding referencedColumn in AstUtil.GetUngroupedAndUnaggregatedColumns(query.GroupByColumns, columnSource.Expression))
                    {
                        if (referencedColumn.Scope == query.QueryScope)
                        {
                            // The column is not an outer reference so this is an error.
                            _errorReporter.SelectExpressionNotAggregatedOrGrouped(referencedColumn);
                        }
                    }
                }

                // Check that all expressions in HAVING are either part of the GROUP BY or are referencing only those
                // columns that are part of the GROUP BY.

                if (query.HavingClause != null)
                {
                    foreach (ColumnRefBinding referencedColumn in AstUtil.GetUngroupedAndUnaggregatedColumns(query.GroupByColumns, query.HavingClause))
                    {
                        if (referencedColumn.Scope == query.QueryScope)
                        {
                            // The column is not an outer reference so this is an error.
                            _errorReporter.HavingExpressionNotAggregatedOrGrouped(referencedColumn);
                        }
                    }
                }

                // Check that all expressions in the ORDER BY clause are either part of the GROUP BY or are
                // referencing only those columns that are part of the GROUP BY.

                if (query.OrderByColumns != null)
                {
                    foreach (OrderByColumn orderByColumn in query.OrderByColumns)
                    {
                        foreach (ColumnRefBinding referencedColumn in AstUtil.GetUngroupedAndUnaggregatedColumns(query.GroupByColumns, orderByColumn.Expression))
                        {
                            if (referencedColumn.Scope == query.QueryScope)
                            {
                                // The column is not an outer reference so this is an error.
                                _errorReporter.OrderByExpressionNotAggregatedOrGrouped(referencedColumn);
                            }
                        }
                    }
                }
            }

            PopQueryScope();
            return result;
        }
コード例 #13
0
ファイル: Algebrizer.cs プロジェクト: chenzuo/nquery
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			// Calculate needed row buffers

			RowBufferCalculator rowBufferCalculator = query.RowBufferCalculator;

			// Emit FROM

			if (query.TableReferences != null)
			{
				Visit(query.TableReferences);
			}
			else
			{
				ConstantScanAlgebraNode constantScanAlgebraNode = new ConstantScanAlgebraNode();
				constantScanAlgebraNode.DefinedValues = new ComputedValueDefinition[0];
				SetLastAlgebraNode(constantScanAlgebraNode);
			}

			// Emit WHERE

			if (query.WhereClause != null)
			{
				FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
				filterAlgebraNode.Input = GetLastAlgebraNode();
				filterAlgebraNode.Predicate = query.WhereClause;
				SetLastAlgebraNode(filterAlgebraNode);
			}

			// Emit GROUP BY

			if (query.GroupByColumns != null || query.IsAggregated)
			{
				EmitComputeScalarIfNeeded(rowBufferCalculator.ComputedGroupColumns);

				List<AggregatedValueDefinition> definedValues = new List<AggregatedValueDefinition>();
				foreach (AggregateExpression aggregateDependency in query.AggregateDependencies)
					definedValues.Add(aggregateDependency.ValueDefinition);

				if (query.GroupByColumns != null)
				{
					SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
					sortAlgebraNode.Input = GetLastAlgebraNode();
					sortAlgebraNode.SortEntries = rowBufferCalculator.GroupColumns;
					sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length);
					SetLastAlgebraNode(sortAlgebraNode);
				}

				AggregateAlgebraNode algebraNode = new AggregateAlgebraNode();
				algebraNode.Input = GetLastAlgebraNode();
				algebraNode.DefinedValues = definedValues.ToArray();
				algebraNode.Groups = rowBufferCalculator.GroupColumns;
				SetLastAlgebraNode(algebraNode);
			}

			// Emit HAVING

			if (query.HavingClause != null)
			{
				FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
				filterAlgebraNode.Input = GetLastAlgebraNode();
				filterAlgebraNode.Predicate = query.HavingClause;
				SetLastAlgebraNode(filterAlgebraNode);
			}

			// Emit compute scalar to calculate expressions needed in SELECT and ORDER BY

			EmitComputeScalarIfNeeded(rowBufferCalculator.ComputedSelectAndOrderColumns);

			// Emit DISTINCT and ORDER BY

			if (query.IsDistinct && query.OrderByColumns != null)
			{
				List<RowBufferEntry> sortEntries = new List<RowBufferEntry>();
				List<SortOrder> sortOrderList = new List<SortOrder>();

				for (int i = 0; i < query.OrderByColumns.Length; i++)
				{
					sortEntries.Add(rowBufferCalculator.OrderColumns[i]);
					sortOrderList.Add(query.OrderByColumns[i].SortOrder);
				}

				foreach (RowBufferEntry selectColumn in rowBufferCalculator.SelectColumns)
				{
					bool selectColumnMustBeSorted = !sortEntries.Contains(selectColumn);
					if (selectColumnMustBeSorted)
					{
						sortEntries.Add(selectColumn);
						sortOrderList.Add(SortOrder.Ascending);
					}
				}

				SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
				sortAlgebraNode.Distinct = true;
				sortAlgebraNode.Input = GetLastAlgebraNode();
				sortAlgebraNode.SortEntries = sortEntries.ToArray();
				sortAlgebraNode.SortOrders = sortOrderList.ToArray();

				SetLastAlgebraNode(sortAlgebraNode);
			}
			else
			{
				if (query.IsDistinct)
				{
					SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
					sortAlgebraNode.Distinct = true;
					sortAlgebraNode.Input = GetLastAlgebraNode();
					sortAlgebraNode.SortEntries = rowBufferCalculator.SelectColumns;
					sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length);
					SetLastAlgebraNode(sortAlgebraNode);
				}

				if (query.OrderByColumns != null)
				{
					List<SortOrder> sortOrderList = new List<SortOrder>();
					foreach (OrderByColumn orderByColumn in query.OrderByColumns)
						sortOrderList.Add(orderByColumn.SortOrder);

					SortAlgebraNode sortAlgebraNode = new SortAlgebraNode();
					sortAlgebraNode.Input = GetLastAlgebraNode();
					sortAlgebraNode.SortEntries = rowBufferCalculator.OrderColumns;
					sortAlgebraNode.SortOrders = sortOrderList.ToArray();
					SetLastAlgebraNode(sortAlgebraNode);
				}
			}

			// Emit TOP

			if (query.TopClause != null)
			{
				TopAlgebraNode algebraNode = new TopAlgebraNode();
				algebraNode.Input = GetLastAlgebraNode();
				algebraNode.Limit = query.TopClause.Value;

				if (query.TopClause.WithTies)
					algebraNode.TieEntries = rowBufferCalculator.OrderColumns;

				SetLastAlgebraNode(algebraNode);
			}

			// Emit select list

			List<string> columnNames = new List<string>();
			foreach (SelectColumn columnSource in query.SelectColumns)
			{
				if (columnSource.Alias != null)
					columnNames.Add(columnSource.Alias.Text);
				else
					columnNames.Add(null);
			}

			ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode();
			resultAlgebraNode.Input = GetLastAlgebraNode();
			resultAlgebraNode.OutputList = rowBufferCalculator.SelectColumns;
			resultAlgebraNode.ColumnNames = columnNames.ToArray();
			SetLastAlgebraNode(resultAlgebraNode);

			return query;
		}
コード例 #14
0
ファイル: XmlProducer.cs プロジェクト: chenzuo/nquery
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			_xmlWriter.WriteStartElement("selectQuery");

			_xmlWriter.WriteStartElement("columns");
			WriteColumns(query.SelectColumns);
			_xmlWriter.WriteEndElement();

			WriteAstNode("from", query.TableReferences);
			WriteAstNode("where", query.WhereClause);

			if (query.GroupByColumns != null)
			{
				_xmlWriter.WriteStartElement("groupBy");

				for (int i = 0; i < query.GroupByColumns.Length; i++)
				{
					ExpressionNode groupByExpression = query.GroupByColumns[i];

					_xmlWriter.WriteStartElement("column");
					_xmlWriter.WriteAttributeString("index", XmlConvert.ToString(i));
					Visit(groupByExpression);
					_xmlWriter.WriteEndElement();
				}
				_xmlWriter.WriteEndElement();
			}

			WriteAstNode("having", query.HavingClause);

			if (query.OrderByColumns != null)
				WriteOrderBy(query.OrderByColumns);

			_xmlWriter.WriteEndElement();

			return query;
		}
コード例 #15
0
ファイル: AggregateBinder.cs プロジェクト: chenzuo/nquery
		public override QueryNode VisitSelectQuery(SelectQuery query)
		{
			_unscopedAggregateExpressionStack.Push(new AggregateList());

			// Visit FROM table references

			if (query.TableReferences != null)
				query.TableReferences = VisitTableReference(query.TableReferences);

			if (QueryHasAggregates(query.QueryScope))
			{
				_errorReporter.AggregateInOn();
				return query;
			}

			// Visit WHERE expression

			if (query.WhereClause != null)
				query.WhereClause = VisitExpression(query.WhereClause);

			if (QueryHasAggregates(query.QueryScope))
			{
				_errorReporter.AggregateInWhere();
				return query;
			}

			// Visit GROUP BY clause

			if (query.GroupByColumns != null)
			{
				for (int i = 0; i < query.GroupByColumns.Length; i++)
					query.GroupByColumns[i] = VisitExpression(query.GroupByColumns[i]);
			}

			if (QueryHasAggregates(query.QueryScope))
			{
				_errorReporter.AggregateInGroupBy();
				return query;
			}

			// Visit select list.

			for (int i = 0; i < query.SelectColumns.Length; i++)
				query.SelectColumns[i].Expression = VisitExpression(query.SelectColumns[i].Expression);

			// Visit having clause.

			if (query.HavingClause != null)
				query.HavingClause = VisitExpression(query.HavingClause);

			// Visit ORDER BY.

			if (query.OrderByColumns != null)
			{
				for (int i = 0; i < query.OrderByColumns.Length; i++)
					query.OrderByColumns[i].Expression = VisitExpression(query.OrderByColumns[i].Expression);
			}

			AggregateList unscopedAggregateList = _unscopedAggregateExpressionStack.Pop();
			ICollection<AggregateExpression> directAggregateDependencies = GetAggregateDependencies(query.QueryScope);

			List<AggregateExpression> aggregateDependencies = new List<AggregateExpression>();
			aggregateDependencies.AddRange(unscopedAggregateList.Values);
			if (directAggregateDependencies != null)
				aggregateDependencies.AddRange(directAggregateDependencies);

			query.AggregateDependencies = aggregateDependencies.ToArray();

			return query;
		}