public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { // Here we don't visit the common table expressions. These are only algebrized if they // are referenced by the actual query. Visit(query.Input); return(query); }
public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements) { CommonTableExpressionQuery result = new CommonTableExpressionQuery(); result.CommonTableExpressions = ArrayHelpers.CreateDeepCopyOfAstElementArray(_commonTableExpressions, alreadyClonedElements); result.Input = (QueryNode)_input.Clone(alreadyClonedElements); return result; }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { _writer.Write("WITH "); bool isFirst = true; foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions) { if (isFirst) { isFirst = false; } else { _writer.Write(","); _writer.WriteLine(); } _writer.Write(commonTableExpression.TableName.ToString()); _writer.Write(" AS ("); _writer.Indent += QUERY_INDENT; _writer.WriteLine(); Visit(commonTableExpression.QueryDeclaration); _writer.Indent -= QUERY_INDENT; _writer.WriteLine(); _writer.Write(")"); } _writer.WriteLine(); Visit(query.Input); return(query); }
private QueryNode ParseQueryWithOptionalCTE() { EnableQueryKeywords(); if (_token.Id != TokenId.WITH) { return(ParseQuery()); } else { NextToken(); CommonTableExpressionQuery commonTableExpressionQuery = new CommonTableExpressionQuery(); List <CommonTableExpression> commonTableExpressions = new List <CommonTableExpression>(); while (_token.Id != TokenId.Eof) { CommonTableExpression commonTableExpression = ParseCommonTableExpression(); commonTableExpressions.Add(commonTableExpression); if (_token.Id != TokenId.Comma) { break; } NextToken(); } commonTableExpressionQuery.CommonTableExpressions = commonTableExpressions.ToArray(); commonTableExpressionQuery.Input = ParseQuery(); return(commonTableExpressionQuery); } }
public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements) { CommonTableExpressionQuery result = new CommonTableExpressionQuery(); result.CommonTableExpressions = ArrayHelpers.CreateDeepCopyOfAstElementArray(_commonTableExpressions, alreadyClonedElements); result.Input = (QueryNode)_input.Clone(alreadyClonedElements); return(result); }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { base.VisitCommonTableExpressionQuery(query); foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions) { EnsureQueryHasNoOrderByUnlessTopSpecified(commonTableExpression.QueryDeclaration); if (commonTableExpression.CommonTableBinding.IsRecursive) { foreach (QueryNode recursiveMember in commonTableExpression.CommonTableBinding.RecursiveMembers) { CommonTableExpressionRecursiveMemberChecker checker = new CommonTableExpressionRecursiveMemberChecker(commonTableExpression.TableName); checker.Visit(recursiveMember); if (checker.RecursiveReferenceInSubquery) { _errorReporter.CteContainsRecursiveReferenceInSubquery(commonTableExpression.TableName); } else if (checker.RecursiveReferences == 0) { _errorReporter.CteContainsUnexpectedAnchorMember(commonTableExpression.TableName); } else if (checker.RecursiveReferences > 1) { _errorReporter.CteContainsMultipleRecursiveReferences(commonTableExpression.TableName); } if (checker.ContainsUnion) { _errorReporter.CteContainsUnion(commonTableExpression.TableName); } if (checker.ContainsDisctinct) { _errorReporter.CteContainsDistinct(commonTableExpression.TableName); } if (checker.ContainsTop) { _errorReporter.CteContainsTop(commonTableExpression.TableName); } if (checker.ContainsOuterJoin) { _errorReporter.CteContainsOuterJoin(commonTableExpression.TableName); } if (checker.ContainsGroupByHavingOrAggregate) { _errorReporter.CteContainsGroupByHavingOrAggregate(commonTableExpression.TableName); } } } } return(query); }
public virtual QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions) { commonTableExpression.QueryDeclaration = VisitQuery(commonTableExpression.QueryDeclaration); } query.Input = VisitQuery(query.Input); return(query); }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { _xmlWriter.WriteStartElement("commonTableExpressionQuery"); _xmlWriter.WriteStartElement("commonTableExpressions"); foreach (CommonTableExpression expression in query.CommonTableExpressions) { _xmlWriter.WriteStartElement("table"); _xmlWriter.WriteAttributeString("name", expression.TableName.ToString()); WriteAstNode("queryDeclaration", expression.QueryDeclaration); _xmlWriter.WriteEndElement(); } _xmlWriter.WriteEndElement(); WriteAstNode("input", query.Input); _xmlWriter.WriteEndElement(); return(query); }
private static bool VisitCommonTableExpressionQuery(CommonTableExpressionQuery node1, CommonTableExpressionQuery node2) { if (node2 == null) { return(false); } if ((node1.Input == null) != (node2.Input == null) || (node1.CommonTableExpressions == null) != (node2.CommonTableExpressions == null) || node1.CommonTableExpressions.Length != node2.CommonTableExpressions.Length) { return(false); } if (node1.Input != null) { if (!Visit(node1.Input, node2.Input)) { return(false); } } if (node1.CommonTableExpressions != null) { for (int i = 0; i < node1.CommonTableExpressions.Length; i++) { if (node1.CommonTableExpressions[i].TableName != node2.CommonTableExpressions[i].TableName) { return(false); } if (!Visit(node1.CommonTableExpressions[i].QueryDeclaration, node2.CommonTableExpressions[i].QueryDeclaration)) { return(false); } } } return(true); }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { _xmlWriter.WriteStartElement("commonTableExpressionQuery"); _xmlWriter.WriteStartElement("commonTableExpressions"); foreach (CommonTableExpression expression in query.CommonTableExpressions) { _xmlWriter.WriteStartElement("table"); _xmlWriter.WriteAttributeString("name", expression.TableName.ToString()); WriteAstNode("queryDeclaration", expression.QueryDeclaration); _xmlWriter.WriteEndElement(); } _xmlWriter.WriteEndElement(); WriteAstNode("input", query.Input); _xmlWriter.WriteEndElement(); return query; }
private static bool VisitCommonTableExpressionQuery(CommonTableExpressionQuery node1, CommonTableExpressionQuery node2) { if (node2 == null) return false; if ((node1.Input == null) != (node2.Input == null) || (node1.CommonTableExpressions == null) != (node2.CommonTableExpressions == null) || node1.CommonTableExpressions.Length != node2.CommonTableExpressions.Length) return false; if (node1.Input != null) if (!Visit(node1.Input, node2.Input)) return false; if (node1.CommonTableExpressions != null) { for (int i = 0; i < node1.CommonTableExpressions.Length; i++) { if (node1.CommonTableExpressions[i].TableName != node2.CommonTableExpressions[i].TableName) return false; if (!Visit(node1.CommonTableExpressions[i].QueryDeclaration, node2.CommonTableExpressions[i].QueryDeclaration)) return false; } } return true; }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { _writer.Write("WITH "); bool isFirst = true; foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions) { if (isFirst) { isFirst = false; } else { _writer.Write(","); _writer.WriteLine(); } _writer.Write(commonTableExpression.TableName.ToString()); _writer.Write(" AS ("); _writer.Indent += QUERY_INDENT; _writer.WriteLine(); Visit(commonTableExpression.QueryDeclaration); _writer.Indent -= QUERY_INDENT; _writer.WriteLine(); _writer.Write(")"); } _writer.WriteLine(); Visit(query.Input); return query; }
private QueryNode ParseQueryWithOptionalCTE() { EnableQueryKeywords(); if (_token.Id != TokenId.WITH) { return ParseQuery(); } else { NextToken(); CommonTableExpressionQuery commonTableExpressionQuery = new CommonTableExpressionQuery(); List<CommonTableExpression> commonTableExpressions = new List<CommonTableExpression>(); while (_token.Id != TokenId.Eof) { CommonTableExpression commonTableExpression = ParseCommonTableExpression(); commonTableExpressions.Add(commonTableExpression); if (_token.Id != TokenId.Comma) break; NextToken(); } commonTableExpressionQuery.CommonTableExpressions = commonTableExpressions.ToArray(); commonTableExpressionQuery.Input = ParseQuery(); return commonTableExpressionQuery; } }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { base.VisitCommonTableExpressionQuery(query); foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions) { EnsureQueryHasNoOrderByUnlessTopSpecified(commonTableExpression.QueryDeclaration); if (commonTableExpression.CommonTableBinding.IsRecursive) { foreach (QueryNode recursiveMember in commonTableExpression.CommonTableBinding.RecursiveMembers) { CommonTableExpressionRecursiveMemberChecker checker = new CommonTableExpressionRecursiveMemberChecker(commonTableExpression.TableName); checker.Visit(recursiveMember); if (checker.RecursiveReferenceInSubquery) _errorReporter.CteContainsRecursiveReferenceInSubquery(commonTableExpression.TableName); else if (checker.RecursiveReferences == 0) _errorReporter.CteContainsUnexpectedAnchorMember(commonTableExpression.TableName); else if (checker.RecursiveReferences > 1) _errorReporter.CteContainsMultipleRecursiveReferences(commonTableExpression.TableName); if (checker.ContainsUnion) _errorReporter.CteContainsUnion(commonTableExpression.TableName); if (checker.ContainsDisctinct) _errorReporter.CteContainsDistinct(commonTableExpression.TableName); if (checker.ContainsTop) _errorReporter.CteContainsTop(commonTableExpression.TableName); if (checker.ContainsOuterJoin) _errorReporter.CteContainsOuterJoin(commonTableExpression.TableName); if (checker.ContainsGroupByHavingOrAggregate) _errorReporter.CteContainsGroupByHavingOrAggregate(commonTableExpression.TableName); } } } return query; }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { QueryScope queryScope = new QueryScope(null); PushNewScope(queryScope); try { foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions) { CommonTableBinding[] existingCommonTables = queryScope.FindCommonTable(commonTableExpression.TableName); if (existingCommonTables != null && existingCommonTables.Length > 0) { ErrorReporter.CteHasDuplicateTableName(commonTableExpression.TableName); break; } // Check if CTE is recursive. bool recursive = IsRecursive(commonTableExpression.QueryDeclaration, commonTableExpression.TableName); if (!recursive) { commonTableExpression.QueryDeclaration = VisitQuery(commonTableExpression.QueryDeclaration); ValidateColumnNames(commonTableExpression.QueryDeclaration.GetColumns(), commonTableExpression); if (ErrorReporter.ErrorsSeen) return query; commonTableExpression.CommonTableBinding = queryScope.DeclareCommonTableExpression(commonTableExpression.TableName, commonTableExpression.QueryDeclaration); } else { // If recursive, we must check the structure. The structure is as follows: // // {One or more anchor members} // UNION ALL // {One or more recursive members} BinaryQuery unionAllQuery = commonTableExpression.QueryDeclaration as BinaryQuery; if (unionAllQuery == null || unionAllQuery.Op != BinaryQueryOperator.UnionAll) { ErrorReporter.CteDoesNotHaveUnionAll(commonTableExpression.TableName); break; } List<QueryNode> recursiveMembers = AstUtil.FlattenBinaryQuery(unionAllQuery); List<QueryNode> anchorMembers = new List<QueryNode>(); foreach (QueryNode queryNode in recursiveMembers) { if (!IsRecursive(queryNode, commonTableExpression.TableName)) anchorMembers.Add(queryNode); else break; } recursiveMembers.RemoveRange(0, anchorMembers.Count); QueryNode anchorMember = AstUtil.CombineQueries(anchorMembers, BinaryQueryOperator.UnionAll); if (anchorMembers.Count == 0) { ErrorReporter.CteDoesNotHaveAnchorMember(commonTableExpression.TableName); return query; } // Resolve anchor member and use it to construct a common table definition. anchorMember = VisitQuery(anchorMember); // Check that all columns have aliases. ValidateColumnNames(anchorMember.GetColumns(), commonTableExpression); if (ErrorReporter.ErrorsSeen) return query; commonTableExpression.CommonTableBinding = queryScope.DeclareCommonTableExpression(commonTableExpression.TableName, anchorMember); SelectColumn[] anchorColumns = anchorMember.GetColumns(); // Now resolve all recursive members and add them to the common table definition. for (int i = 0; i < recursiveMembers.Count; i++) { recursiveMembers[i] = VisitQuery(recursiveMembers[i]); // Make sure the column count and data type match. // NOTE: Due to the recursive nature there is no implicit conversion support for the UNION ALL // in common table expressions. Instead, the types must match exactly. SelectColumn[] recursiveColumns = recursiveMembers[i].GetColumns(); if (recursiveColumns.Length != anchorColumns.Length) ErrorReporter.DifferentExpressionCountInBinaryQuery(); else { for (int columnIndex = 0; columnIndex < anchorColumns.Length; columnIndex++) { Type anchorColumnType = anchorColumns[columnIndex].Expression.ExpressionType; Type recursiveColumnType = recursiveColumns[columnIndex].Expression.ExpressionType; if (recursiveColumnType != null && recursiveColumnType != anchorColumnType) ErrorReporter.CteHasTypeMismatchBetweenAnchorAndRecursivePart(anchorColumns[columnIndex].Alias, commonTableExpression.TableName); } } } commonTableExpression.CommonTableBinding.RecursiveMembers = recursiveMembers.ToArray(); } } if (ErrorReporter.ErrorsSeen) return query; query.Input = VisitQuery(query.Input); } finally { PopScope(); } return query; }
public override QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { // Here we don't visit the common table expressions. These are only algebrized if they // are referenced by the actual query. Visit(query.Input); return query; }
public virtual QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query) { foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions) commonTableExpression.QueryDeclaration = VisitQuery(commonTableExpression.QueryDeclaration); query.Input = VisitQuery(query.Input); return query; }