Example #1
0
 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;
		}
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        public virtual QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query)
        {
            foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions)
            {
                commonTableExpression.QueryDeclaration = VisitQuery(commonTableExpression.QueryDeclaration);
            }

            query.Input = VisitQuery(query.Input);
            return(query);
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
		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;
		}
Example #11
0
		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;
		}
Example #12
0
		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;
		}
Example #13
0
        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;
            }
        }
Example #14
0
        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;
        }
Example #15
0
        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;
        }
Example #16
0
		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;
		}
Example #17
0
		public virtual QueryNode VisitCommonTableExpressionQuery(CommonTableExpressionQuery query)
		{
			foreach (CommonTableExpression commonTableExpression in query.CommonTableExpressions)
				commonTableExpression.QueryDeclaration = VisitQuery(commonTableExpression.QueryDeclaration);

			query.Input = VisitQuery(query.Input);
			return query;
		}