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; }
public override QueryNode VisitSelectQuery(SelectQuery query) { base.VisitSelectQuery(query); RowBufferCalculator rowBufferCalculator = new RowBufferCalculator(query); rowBufferCalculator.Calculate(); query.RowBufferCalculator = rowBufferCalculator; return query; }
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; }
public RowBufferCalculator(SelectQuery selectQuery) { _selectQuery = selectQuery; }
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); }
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; }
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; }
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; }
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; }
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(); } }
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; }
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; }
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; }
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; }
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; }