예제 #1
0
 private static bool VisitAllAnySubselect(AllAnySubselect node1, AllAnySubselect node2)
 {
     return(node2 != null &&
            node1.Type == node2.Type &&
            node1.Op == node2.Op &&
            Visit(node1.Left, node2.Left) &&
            Visit(node1.Query, node2.Query));
 }
예제 #2
0
 public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
 {
     EnsureSubqueryNotNestedInAggregate();
     base.VisitAllAnySubselect(expression);
     EnsureQueryHasOneColumnOnly(expression.Query);
     EnsureQueryHasNoOrderByUnlessTopSpecified(expression.Query);
     return(expression);
 }
예제 #3
0
파일: Validator.cs 프로젝트: chenzuo/nquery
 public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
 {
     EnsureSubqueryNotNestedInAggregate();
     base.VisitAllAnySubselect(expression);
     EnsureQueryHasOneColumnOnly(expression.Query);
     EnsureQueryHasNoOrderByUnlessTopSpecified(expression.Query);
     return expression;
 }
예제 #4
0
		public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements)
		{
			AllAnySubselect allAnySubselect = new AllAnySubselect();
			allAnySubselect.Left = (ExpressionNode)_left.Clone(alreadyClonedElements);
			allAnySubselect.Op = _op;
			allAnySubselect.Type = _type;
			allAnySubselect.Query = (QueryNode)Query.Clone(alreadyClonedElements);
			return allAnySubselect;
		}
예제 #5
0
        public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
        {
            expression.Left = VisitExpression(expression.Left);
            ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query);

            ExpressionNode leftExpression = expression.Left;
            RowBufferEntryExpression rightExpression = new RowBufferEntryExpression();
            rightExpression.RowBufferEntry = algebrizedQuery.OutputList[0];

            ExpressionBuilder expressionBuilder = new ExpressionBuilder();
            expressionBuilder.Push(leftExpression);
            expressionBuilder.Push(rightExpression);
            expressionBuilder.PushBinary(expression.Op);

            bool negated = (expression.Type == AllAnySubselect.AllAnyType.All);
            if (negated)
            {
                expressionBuilder.PushUnary(UnaryOperator.LogicalNot);
                expressionBuilder.Push(leftExpression);
                expressionBuilder.PushIsNull();
                expressionBuilder.Push(rightExpression);
                expressionBuilder.PushIsNull();
                expressionBuilder.PushNAry(LogicalOperator.Or);
            }

            ExpressionNode filterPredicate = expressionBuilder.Pop();

            FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
            filterAlgebraNode.Input = algebrizedQuery;
            filterAlgebraNode.Predicate = filterPredicate;

            AlgebraNode input = GetAndResetLastNode();

            if (!negated && !ProbingEnabled && input == null)
            {
                SetLastAlgebraNode(filterAlgebraNode);
                return LiteralExpression.FromBoolean(true);
            }
            else
            {
                if (input == null)
                    input = CreateConstantScan();

                RowBufferEntry probeColumn = CreateProbeColumn();

                JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
                joinAlgebraNode.ProbeBufferEntry = probeColumn;
                joinAlgebraNode.Left = input;
                joinAlgebraNode.Right = filterAlgebraNode;
                joinAlgebraNode.Op = negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin;

                SetLastAlgebraNode(joinAlgebraNode);
                return CreateProbeColumnRef(probeColumn);
            }
        }
예제 #6
0
        public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements)
        {
            AllAnySubselect allAnySubselect = new AllAnySubselect();

            allAnySubselect.Left  = (ExpressionNode)_left.Clone(alreadyClonedElements);
            allAnySubselect.Op    = _op;
            allAnySubselect.Type  = _type;
            allAnySubselect.Query = (QueryNode)Query.Clone(alreadyClonedElements);
            return(allAnySubselect);
        }
예제 #7
0
 public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
 {
     _subqueryContextCounter++;
     try
     {
         return(base.VisitAllAnySubselect(expression));
     }
     finally
     {
         _subqueryContextCounter--;
     }
 }
		public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
		{
			_subqueryContextCounter++;
			try
			{
				return base.VisitAllAnySubselect(expression);
			}
			finally
			{
				_subqueryContextCounter--;
			}
		}
예제 #9
0
        public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
        {
            _xmlWriter.WriteStartElement("allAnySubselect");
            _xmlWriter.WriteAttributeString("op", expression.Op.TokenText);
            _xmlWriter.WriteAttributeString("type", expression.Type.ToString());
            WriteTypeAttribute(expression.ExpressionType);

            WriteAstNode("left", expression.Left);
            WriteAstNode("query", expression.Query);

            _xmlWriter.WriteEndElement();

            return(expression);
        }
예제 #10
0
        public override ExpressionNode VisitInExpression(InExpression expression)
        {
            // First visit right expressions
            base.VisitInExpression(expression);

            // Check if the IN expression should have been expr = ANY (suquery)

            if (expression.RightExpressions.Length == 1)
            {
                SingleRowSubselect firstElemenAsSubselect = expression.RightExpressions[0] as SingleRowSubselect;

                if (firstElemenAsSubselect != null)
                {
                    AllAnySubselect result = new AllAnySubselect();
                    result.Type  = AllAnySubselect.AllAnyType.Any;
                    result.Left  = expression.Left;
                    result.Op    = BinaryOperator.Equal;
                    result.Query = firstElemenAsSubselect.Query;
                    return(result);
                }
            }

            // IN-expressions can be written as a chain of OR and = expressions:
            //
            // leftExpr IN (rightExpr1 , ... , rightExprN)
            //
            // (leftExpr = rightExpr1) OR (...) OR (leftExpr = rightExprN)

            ExpressionNode resultNode = null;

            foreach (ExpressionNode rightExpression in expression.RightExpressions)
            {
                ExpressionNode   clonedLeft      = (ExpressionNode)expression.Left.Clone();
                BinaryExpression comparisionNode = new BinaryExpression(BinaryOperator.Equal, clonedLeft, rightExpression);

                if (resultNode == null)
                {
                    resultNode = comparisionNode;
                }
                else
                {
                    BinaryExpression orNode = new BinaryExpression(BinaryOperator.LogicalOr, resultNode, comparisionNode);
                    resultNode = orNode;
                }
            }

            // Visit resulting expression.
            return(VisitExpression(resultNode));
        }
예제 #11
0
        public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
        {
            Visit(expression.Left);

            _writer.Write(" ");
            _writer.Write(expression.Op.TokenText);
            _writer.Write(" ");

            if (expression.Type == AllAnySubselect.AllAnyType.All)
            {
                _writer.Write("ALL (");
            }
            else
            {
                _writer.Write("ANY (");
            }

            Visit(expression.Query);
            _writer.Write(")");

            return(expression);
        }
 public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
 {
     return(expression);
 }
예제 #13
0
 public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
 {
     _containsExistenceSubselects = true;
     VisitQueryExpression(expression.Query);
     return(expression);
 }
예제 #14
0
파일: Comparer.cs 프로젝트: chenzuo/nquery
		private static bool VisitAllAnySubselect(AllAnySubselect node1, AllAnySubselect node2)
		{
			return node2 != null &&
			       node1.Type == node2.Type &&
			       node1.Op == node2.Op &&
			       Visit(node1.Left, node2.Left) &&
			       Visit(node1.Query, node2.Query);
		}
예제 #15
0
		public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
		{
			Visit(expression.Left);

			_writer.Write(" ");
			_writer.Write(expression.Op.TokenText);
			_writer.Write(" ");

			if (expression.Type == AllAnySubselect.AllAnyType.All)
				_writer.Write("ALL (");
			else
				_writer.Write("ANY (");

			Visit(expression.Query);
			_writer.Write(")");

			return expression;
		}
예제 #16
0
파일: Parser.cs 프로젝트: chenzuo/nquery
        private ExpressionNode ParseSubExpression(ExpressionNode left, int precedence)
        {
            if (left == null)
            {
                // No left operand, so we parse one and take care about leading unary operators

                if (_token.Info.UnaryOperator != null)
                {
                    UnaryOperator op = _token.Info.UnaryOperator;

                    NextToken();

                    ExpressionNode expr = ParseSubExpression(null, op.Precedence);
                    left = new UnaryExpression(op, expr);
                }
                else
                {
                    left = ParseSimpleExpression();
                }
            }

            while (_token.Id != TokenId.Eof)
            {
                // Special handling for NOT BETWEEN, NOT IN, NOT LIKE, NOT SIMILAR TO, and NOT SOUNDSLIKE.

                bool negated = false;

                if (_token.Id == TokenId.NOT)
                {
                    if (_lookahead.Id == TokenId.BETWEEN ||
                        _lookahead.Id == TokenId.IN ||
                        _lookahead.Id == TokenId.LIKE ||
                        _lookahead.Id == TokenId.SIMILAR ||
                        _lookahead.Id == TokenId.SOUNDSLIKE)
                    {
                        NextToken();
                        negated = true;
                    }
                }

                // Special handling for the only ternary operator BETWEEN

                if (_token.Id == TokenId.BETWEEN)
                {
                    NextToken();
                    ExpressionNode lowerBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);
                    Match(TokenId.AND);
                    ExpressionNode upperBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);

                    left = new BetweenExpression(left, lowerBound, upperBound);
                }
                else
                {
                    // If there is no binary operator we are finished

                    if (_token.Info.BinaryOperator == null)
                        break;

                    BinaryOperator binaryOp = _token.Info.BinaryOperator;

                    // Precedence is lower, parse it later

                    if (binaryOp.Precedence < precedence)
                        break;

                    // Precedence is equal, but operator ist not right associative, parse it later

                    if (binaryOp.Precedence == precedence && !binaryOp.IsRightAssociative)
                        break;

                    // Precedence is higher

                    NextToken();

                    // Special handling for SIMILAR TO

                    if (binaryOp == BinaryOperator.SimilarTo)
                        Match(TokenId.TO);

                    if (binaryOp == BinaryOperator.In)
                    {
                        // Special handling for IN

                        InExpression inExpression = new InExpression();
                        inExpression.Left = left;
                        inExpression.RightExpressions = ParseSimpleQueryExpressionList();
                        left = inExpression;
                    }
                    else if (_token.Id == TokenId.ANY || _token.Id == TokenId.SOME || _token.Id == TokenId.ALL)
                    {
                        // Special handling for ANY (SOME) and ALL

                        if (binaryOp != BinaryOperator.Equal &&
                            binaryOp != BinaryOperator.NotEqual &&
                            binaryOp != BinaryOperator.Less &&
                            binaryOp != BinaryOperator.LessOrEqual &&
                            binaryOp != BinaryOperator.Greater &&
                            binaryOp != BinaryOperator.GreaterOrEqual)
                        {
                            _errorReporter.InvalidOperatorForAllAny(_token.Range, binaryOp);
                        }

                        AllAnySubselect allAnySubselect = new AllAnySubselect();
                        allAnySubselect.Left = left;
                        allAnySubselect.Op = binaryOp;
                        allAnySubselect.Type = (_token.Id == TokenId.ALL) ? AllAnySubselect.AllAnyType.All : AllAnySubselect.AllAnyType.Any;
                        NextToken();
                        Match(TokenId.LeftParentheses);
                        allAnySubselect.Query = ParseQuery();
                        Match(TokenId.RightParentheses);
                        left = allAnySubselect;
                    }
                    else
                    {
                        left = new BinaryExpression(binaryOp, left, ParseSubExpression(null, binaryOp.Precedence));
                    }
                }

                // Special handling for negated expressions (see above)

                if (negated)
                    left = new UnaryExpression(UnaryOperator.LogicalNot, left);
            }

            return left;
        }
예제 #17
0
 public virtual ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
 {
     expression.Left  = VisitExpression(expression.Left);
     expression.Query = VisitQuery(expression.Query);
     return(expression);
 }
예제 #18
0
		public override ExpressionNode VisitInExpression(InExpression expression)
		{
			// First visit right expressions
			base.VisitInExpression(expression);
			
			// Check if the IN expression should have been expr = ANY (suquery)
			
			if (expression.RightExpressions.Length == 1)
			{
				SingleRowSubselect firstElemenAsSubselect = expression.RightExpressions[0] as SingleRowSubselect;
				
				if (firstElemenAsSubselect != null)
				{
                    AllAnySubselect result = new AllAnySubselect();
                    result.Type = AllAnySubselect.AllAnyType.Any;
                    result.Left = expression.Left;
                    result.Op = BinaryOperator.Equal;
                    result.Query = firstElemenAsSubselect.Query;
					return result;
				}
			}
			
			// IN-expressions can be written as a chain of OR and = expressions:
			//
			// leftExpr IN (rightExpr1 , ... , rightExprN)
			//
			// (leftExpr = rightExpr1) OR (...) OR (leftExpr = rightExprN)

			ExpressionNode resultNode = null;

			foreach (ExpressionNode rightExpression in expression.RightExpressions)
			{
				ExpressionNode clonedLeft = (ExpressionNode) expression.Left.Clone();
				BinaryExpression comparisionNode = new BinaryExpression(BinaryOperator.Equal, clonedLeft, rightExpression);
				
				if (resultNode == null)
					resultNode = comparisionNode;
				else
				{
					BinaryExpression orNode = new BinaryExpression(BinaryOperator.LogicalOr, resultNode, comparisionNode);
					resultNode = orNode;
				}
			}

			// Visit resulting expression.
			return VisitExpression(resultNode);
		}
예제 #19
0
		public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
		{
			_xmlWriter.WriteStartElement("allAnySubselect");
			_xmlWriter.WriteAttributeString("op", expression.Op.TokenText);
			_xmlWriter.WriteAttributeString("type", expression.Type.ToString());
			WriteTypeAttribute(expression.ExpressionType);

			WriteAstNode("left", expression.Left);
			WriteAstNode("query", expression.Query);

			_xmlWriter.WriteEndElement();

			return expression;
		}
 public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
 {
     return expression;
 }
예제 #21
0
        private ExpressionNode ParseSubExpression(ExpressionNode left, int precedence)
        {
            if (left == null)
            {
                // No left operand, so we parse one and take care about leading unary operators

                if (_token.Info.UnaryOperator != null)
                {
                    UnaryOperator op = _token.Info.UnaryOperator;

                    NextToken();

                    ExpressionNode expr = ParseSubExpression(null, op.Precedence);
                    left = new UnaryExpression(op, expr);
                }
                else
                {
                    left = ParseSimpleExpression();
                }
            }

            while (_token.Id != TokenId.Eof)
            {
                // Special handling for NOT BETWEEN, NOT IN, NOT LIKE, NOT SIMILAR TO, and NOT SOUNDSLIKE.

                bool negated = false;

                if (_token.Id == TokenId.NOT)
                {
                    if (_lookahead.Id == TokenId.BETWEEN ||
                        _lookahead.Id == TokenId.IN ||
                        _lookahead.Id == TokenId.LIKE ||
                        _lookahead.Id == TokenId.SIMILAR ||
                        _lookahead.Id == TokenId.SOUNDSLIKE)
                    {
                        NextToken();
                        negated = true;
                    }
                }

                // Special handling for the only ternary operator BETWEEN

                if (_token.Id == TokenId.BETWEEN)
                {
                    NextToken();
                    ExpressionNode lowerBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);
                    Match(TokenId.AND);
                    ExpressionNode upperBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);

                    left = new BetweenExpression(left, lowerBound, upperBound);
                }
                else
                {
                    // If there is no binary operator we are finished

                    if (_token.Info.BinaryOperator == null)
                    {
                        break;
                    }

                    BinaryOperator binaryOp = _token.Info.BinaryOperator;

                    // Precedence is lower, parse it later

                    if (binaryOp.Precedence < precedence)
                    {
                        break;
                    }

                    // Precedence is equal, but operator ist not right associative, parse it later

                    if (binaryOp.Precedence == precedence && !binaryOp.IsRightAssociative)
                    {
                        break;
                    }

                    // Precedence is higher

                    NextToken();

                    // Special handling for SIMILAR TO

                    if (binaryOp == BinaryOperator.SimilarTo)
                    {
                        Match(TokenId.TO);
                    }

                    if (binaryOp == BinaryOperator.In)
                    {
                        // Special handling for IN

                        InExpression inExpression = new InExpression();
                        inExpression.Left             = left;
                        inExpression.RightExpressions = ParseSimpleQueryExpressionList();
                        left = inExpression;
                    }
                    else if (_token.Id == TokenId.ANY || _token.Id == TokenId.SOME || _token.Id == TokenId.ALL)
                    {
                        // Special handling for ANY (SOME) and ALL

                        if (binaryOp != BinaryOperator.Equal &&
                            binaryOp != BinaryOperator.NotEqual &&
                            binaryOp != BinaryOperator.Less &&
                            binaryOp != BinaryOperator.LessOrEqual &&
                            binaryOp != BinaryOperator.Greater &&
                            binaryOp != BinaryOperator.GreaterOrEqual)
                        {
                            _errorReporter.InvalidOperatorForAllAny(_token.Range, binaryOp);
                        }

                        AllAnySubselect allAnySubselect = new AllAnySubselect();
                        allAnySubselect.Left = left;
                        allAnySubselect.Op   = binaryOp;
                        allAnySubselect.Type = (_token.Id == TokenId.ALL) ? AllAnySubselect.AllAnyType.All : AllAnySubselect.AllAnyType.Any;
                        NextToken();
                        Match(TokenId.LeftParentheses);
                        allAnySubselect.Query = ParseQuery();
                        Match(TokenId.RightParentheses);
                        left = allAnySubselect;
                    }
                    else
                    {
                        left = new BinaryExpression(binaryOp, left, ParseSubExpression(null, binaryOp.Precedence));
                    }
                }

                // Special handling for negated expressions (see above)

                if (negated)
                {
                    left = new UnaryExpression(UnaryOperator.LogicalNot, left);
                }
            }

            return(left);
        }
예제 #22
0
        public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
        {
            expression.Left = VisitExpression(expression.Left);
            ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query);

            ExpressionNode           leftExpression  = expression.Left;
            RowBufferEntryExpression rightExpression = new RowBufferEntryExpression();

            rightExpression.RowBufferEntry = algebrizedQuery.OutputList[0];

            ExpressionBuilder expressionBuilder = new ExpressionBuilder();

            expressionBuilder.Push(leftExpression);
            expressionBuilder.Push(rightExpression);
            expressionBuilder.PushBinary(expression.Op);

            bool negated = (expression.Type == AllAnySubselect.AllAnyType.All);

            if (negated)
            {
                expressionBuilder.PushUnary(UnaryOperator.LogicalNot);
                expressionBuilder.Push(leftExpression);
                expressionBuilder.PushIsNull();
                expressionBuilder.Push(rightExpression);
                expressionBuilder.PushIsNull();
                expressionBuilder.PushNAry(LogicalOperator.Or);
            }

            ExpressionNode filterPredicate = expressionBuilder.Pop();

            FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();

            filterAlgebraNode.Input     = algebrizedQuery;
            filterAlgebraNode.Predicate = filterPredicate;

            AlgebraNode input = GetAndResetLastNode();

            if (!negated && !ProbingEnabled && input == null)
            {
                SetLastAlgebraNode(filterAlgebraNode);
                return(LiteralExpression.FromBoolean(true));
            }
            else
            {
                if (input == null)
                {
                    input = CreateConstantScan();
                }

                RowBufferEntry probeColumn = CreateProbeColumn();

                JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
                joinAlgebraNode.ProbeBufferEntry  = probeColumn;
                joinAlgebraNode.Left  = input;
                joinAlgebraNode.Right = filterAlgebraNode;
                joinAlgebraNode.Op    = negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin;

                SetLastAlgebraNode(joinAlgebraNode);
                return(CreateProbeColumnRef(probeColumn));
            }
        }
예제 #23
0
        public override ExpressionNode VisitUnaryExpression(UnaryExpression expression)
        {
            // First visit arguments
            base.VisitUnaryExpression(expression);

            if (expression.Op == UnaryOperator.LogicalNot)
            {
                // Replace "NOT NOT expr" by "expr"

                UnaryExpression unOp = expression.Operand as UnaryExpression;
                if (unOp != null)
                {
                    if (unOp.Op == UnaryOperator.LogicalNot)
                    {
                        return(VisitExpression(unOp.Operand));
                    }
                }

                // Replace "NOT expr IS NULL" and "NOT expr IS NOT NULL" by
                //         "expr IS NOT NULL" and "expr IS NULL" resp.

                IsNullExpression isNull = expression.Operand as IsNullExpression;
                if (isNull != null)
                {
                    isNull.Negated = !isNull.Negated;
                    return(VisitExpression(isNull));
                }

                // Apply negation on EXISTS

                ExistsSubselect existsSubselect = expression.Operand as ExistsSubselect;
                if (existsSubselect != null)
                {
                    existsSubselect.Negated = !existsSubselect.Negated;
                    return(existsSubselect);
                }

                // Apply negation on ALL/ANY subquery

                AllAnySubselect allAnySubselect = expression.Operand as AllAnySubselect;
                if (allAnySubselect != null)
                {
                    allAnySubselect.Op   = AstUtil.NegateBinaryOp(allAnySubselect.Op);
                    allAnySubselect.Type = (allAnySubselect.Type == AllAnySubselect.AllAnyType.All) ? AllAnySubselect.AllAnyType.Any : AllAnySubselect.AllAnyType.All;
                    return(allAnySubselect);
                }

                // Apply De Morgan's law

                BinaryExpression binOp = expression.Operand as BinaryExpression;

                if (binOp != null)
                {
                    BinaryOperator negatedOp = AstUtil.NegateBinaryOp(binOp.Op);

                    if (negatedOp != null)
                    {
                        ExpressionNode newLeft;
                        ExpressionNode newRight;

                        if (binOp.Op == BinaryOperator.LogicalAnd || binOp.Op == BinaryOperator.LogicalOr)
                        {
                            newLeft  = new UnaryExpression(expression.Op, binOp.Left);
                            newRight = new UnaryExpression(expression.Op, binOp.Right);
                        }
                        else
                        {
                            newLeft  = binOp.Left;
                            newRight = binOp.Right;
                        }

                        binOp.Op    = negatedOp;
                        binOp.Left  = newLeft;
                        binOp.Right = newRight;
                        return(VisitExpression(binOp));
                    }
                }
            }

            return(expression);
        }
예제 #24
0
		public virtual ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
		{
			expression.Left = VisitExpression(expression.Left);
			expression.Query = VisitQuery(expression.Query);
			return expression;
		}
예제 #25
0
		public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression)
		{
            _containsExistenceSubselects = true;
            VisitQueryExpression(expression.Query);
			return expression;
		}