Esempio n. 1
0
 public void PushBinary(BinaryOperator binaryOperator)
 {
     ExpressionNode rightExpressionNode = _expressionStack.Pop();
     ExpressionNode leftExpressionNode = _expressionStack.Pop();
     BinaryExpression binaryExpression = new BinaryExpression(binaryOperator, leftExpressionNode, rightExpressionNode);
     _expressionStack.Push(binaryExpression);
 }
Esempio n. 2
0
		public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
		{
			if (expression.Op == BinaryOperator.LogicalOr)
			{
				// Special handling for logical OR:
				// For logical OR both arguments must be NULL to yield false/null.
				
				Visit(expression.Left);
				bool leftIsNullOrFalse = _lastExpressionsYieldsNullOrFalse;
				Visit(expression.Right);
				
				_lastExpressionsYieldsNullOrFalse = leftIsNullOrFalse && _lastExpressionsYieldsNullOrFalse;
			}
			else
			{
				// In all other cases we know the result will be false/null if
				// any operand is null.

				Visit(expression.Left);
				bool leftIsNullOrFalse = _lastExpressionsYieldsNullOrFalse;
				Visit(expression.Right);
				
				_lastExpressionsYieldsNullOrFalse = leftIsNullOrFalse || _lastExpressionsYieldsNullOrFalse;
			}
			
			return expression;
		}
Esempio n. 3
0
		public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
		{
			base.VisitBinaryExpression(expression);

			ConstantExpression leftConstant = expression.Left as ConstantExpression;
			ConstantExpression rightConstant = expression.Right as ConstantExpression;

			if (leftConstant != null && rightConstant != null)
			{
				// Both operands are constants, compute the result and return a constant node.

				try
				{
                    return LiteralExpression.FromTypedValue(expression.GetValue(), expression.ExpressionType);
				}
				catch (RuntimeException ex)
				{
					_errorReporter.CannotFoldConstants(ex);
				}
			}
			else if ((leftConstant != null || rightConstant != null) && (expression.Op == BinaryOperator.LogicalAnd || expression.Op == BinaryOperator.LogicalOr))
			{
				// We have a boolean AND or OR expression where one operand is a constant. Check if we
				// already know the result.

				if (expression.Op == BinaryOperator.LogicalAnd)
				{
					// Check if one operand is false

					if (leftConstant != null && !leftConstant.IsNullValue && !leftConstant.AsBoolean ||
						rightConstant != null && !rightConstant.IsNullValue && !rightConstant.AsBoolean)
						return LiteralExpression.FromBoolean(false);
				}
				else
				{
					// Check if one operand is true

					if (leftConstant != null && !leftConstant.IsNullValue && leftConstant.AsBoolean ||
						rightConstant != null && !rightConstant.IsNullValue && rightConstant.AsBoolean)
						return LiteralExpression.FromBoolean(true);
				}

				// We don't know the result but we can throw away the and/or expression
				// by replacing it with the unknown part.

				if (leftConstant != null && !leftConstant.IsNullValue)
					return expression.Right;
				else if (rightConstant != null && !rightConstant.IsNullValue)
					return expression.Left;

				return expression;
			}

			// If we getting here we return the orginal one.

			return expression;
		}
Esempio n. 4
0
		public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements)
		{
			BinaryExpression result = new BinaryExpression();
			result.Op = _op;
			result.Left = (ExpressionNode) _left.Clone(alreadyClonedElements);
			result.Right = (ExpressionNode) _right.Clone(alreadyClonedElements);
			result.OperatorMethod = OperatorMethod;
			return result;
		}
Esempio n. 5
0
		public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
		{
			base.VisitBinaryExpression(expression);

			Type leftType = expression.Left.ExpressionType;
			Type rightType = expression.Right.ExpressionType;

			if (leftType == null || rightType == null)
			{
				expression.OperatorMethod = null;
			}
			else if (expression.Op == BinaryOperator.LogicalAnd ||expression.Op == BinaryOperator.LogicalOr)
			{
				// If an operand of this expression is of type NULL the whole expression would be of type
				// NULL (because any operator containing NULL will yield NULL). But Boolean conditions
				// are an exception to this rule. This is why there is no operator method in the builtin operators
				// that calculculates OR or AND. Instead, there is custom IL emitted for these operators.
				//
				// This expression will never use the operator method. The binder will return a placeholder.

				if (expression.Left.ExpressionType != typeof(bool) && expression.Left.ExpressionType != typeof(DBNull) ||
					expression.Right.ExpressionType != typeof(bool) && expression.Right.ExpressionType != typeof(DBNull))
				{
					// We only accept Boolean and NULL datatypes as argument to OR and AND.
					_errorReporter.CannotApplyOperator(expression.Op, expression.Left.ExpressionType, expression.Right.ExpressionType);
				}

				expression.OperatorMethod = _binder.BindOperator(expression.Op, typeof(bool), typeof(bool));
			}
			else
			{
				expression.OperatorMethod = _binder.BindOperator(expression.Op, leftType, rightType);

				if (expression.OperatorMethod == null)
				{
					_errorReporter.CannotApplyOperator(expression.Op, leftType, rightType);
				}
				else
				{
					// Convert operands if necessary

					ParameterInfo[] opMethodParams = expression.OperatorMethod.GetParameters();
					expression.Left = _binder.ConvertExpressionIfRequired(expression.Left, opMethodParams[0].ParameterType);
					expression.Right = _binder.ConvertExpressionIfRequired(expression.Right, opMethodParams[1].ParameterType);
				}
			}

			return expression;
		}
Esempio n. 6
0
            public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
            {
                if (expression.Op == BinaryOperator.LogicalAnd)
                {
                    return base.VisitBinaryExpression(expression);
                }
                else if (expression.Op == BinaryOperator.Equal)
                {
                    RowBufferEntry[] leftRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Left);
                    RowBufferEntry[] rightRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Right);

                    if (leftRowBufferEntries.Length == 1 && rightRowBufferEntries.Length == 1)
                    {
                        RowBufferEntry leftRowBufferEntry = leftRowBufferEntries[0];
                        RowBufferEntry rightRowBufferEntry = rightRowBufferEntries[0];
                        bool leftIsOuter = IsOuterReference(leftRowBufferEntry);
                        bool rightIsOuter = IsOuterReference(rightRowBufferEntry);

                        if (leftRowBufferEntry != rightRowBufferEntry && leftIsOuter ^ rightIsOuter)
                        {
                            // Both expressions depend on extactly one row buffer entry but
                            // they are not refering to the same row buffer entry and
                            // only one is an outer reference.

                            SpoolExpression spoolExpression = new SpoolExpression();
                            if (leftIsOuter)
                            {
                                spoolExpression.IndexExpression = expression.Right;
                                spoolExpression.ProbeExpression = expression.Left;
                            }
                            else
                            {
                                spoolExpression.IndexExpression = expression.Left;
                                spoolExpression.ProbeExpression = expression.Right;
                            }

                            _spoolExpressions.Add(spoolExpression);
                            return LiteralExpression.FromBoolean(true);
                        }
                    }
                }

                return expression;
            }
Esempio n. 7
0
		public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
		{
			// Emit left operand

			bool parenthesesNedded = NeedParentheses(expression.Left, expression.Op.Precedence, false);

			if (parenthesesNedded)
				_writer.Write("(");

			Visit(expression.Left);

			if (parenthesesNedded)
				_writer.Write(")");

			// Emit operator

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

			// Emit right operand

			parenthesesNedded = NeedParentheses(expression.Right, expression.Op.Precedence, true);

			if (parenthesesNedded)
				_writer.Write("(");

			Visit(expression.Right);

			if (parenthesesNedded)
				_writer.Write(")");

			return expression;
		}
Esempio n. 8
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;
        }
Esempio n. 9
0
	    public override ExpressionNode VisitBetweenExpression(BetweenExpression expression)
		{
			// First visit all expressions
			base.VisitBetweenExpression(expression);

			// Since a BETWEEN expression can be expressed using an AND expression and two
			// <= binary operator nodes we convert them to simplify the join and optimization engine.

			BinaryExpression lowerBound = new BinaryExpression(BinaryOperator.LessOrEqual, expression.LowerBound, expression.Expression);
			BinaryExpression upperBound = new BinaryExpression(BinaryOperator.LessOrEqual, expression.Expression, expression.UpperBound);
			BinaryExpression and = new BinaryExpression(BinaryOperator.LogicalAnd, lowerBound, upperBound);

			// Make sure we also resolve the result.
			return VisitExpression(and);
		}
Esempio n. 10
0
		public override ExpressionNode VisitCaseExpression(CaseExpression expression)
		{
			// Replace simple CASE by searched CASE, i.e.
			//
			// replace
			//
			//       CASE InputExpr
			//          WHEN Expr1 THEN ThenExpr1 ...
			//          WHEN ExprN THEN ThenExprN
			//          [ELSE ElseExpr]
			//       END
			//
			// by
			//
			//       CASE
			//          WHEN InputExpr = Expr1 THEN ThenExpr1 ...
			//          WHEN InputExpr = ExprN THEN ThenExprN
			//          [ELSE ElseExpr]
			//       END

			if (expression.InputExpression != null)
			{
				for (int i = 0; i < expression.WhenExpressions.Length; i++)
				{
					BinaryExpression binaryExpression = new BinaryExpression();
					binaryExpression.Op = BinaryOperator.Equal;
					binaryExpression.Left = (ExpressionNode) expression.InputExpression.Clone();
					binaryExpression.Right = expression.WhenExpressions[i];
					expression.WhenExpressions[i] = binaryExpression;
				}

				expression.InputExpression = null;
			}

			return base.VisitCaseExpression(expression);
		}
Esempio n. 11
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);
		}
Esempio n. 12
0
		public virtual ExpressionNode VisitBinaryExpression(BinaryExpression expression)
		{
			expression.Left = VisitExpression(expression.Left);
			expression.Right = VisitExpression(expression.Right);
			return expression;
		}
Esempio n. 13
0
		public ExpressionNode ToExpression()
		{
			BinaryOperator op;

			switch (_op)
			{
				case JoinOperator.Equal:
					op = BinaryOperator.Equal;
					break;
				case JoinOperator.Less:
					op = BinaryOperator.Less;
					break;
				case JoinOperator.LessOrEqual:
					op = BinaryOperator.LessOrEqual;
					break;
				case JoinOperator.Greater:
					op = BinaryOperator.Greater;
					break;
				case JoinOperator.GreaterOrEqual:
					op = BinaryOperator.GreaterOrEqual;
					break;
				default:
					throw ExceptionBuilder.UnhandledCaseLabel(_op);
			}

			// HACK: Here we need to create a fully resolved binary expression node
			//       Using the code (Binder.BindOperator) is NOT the way it should be...

			Binder binder = new Binder(ExceptionErrorProvider.Instance);
			BinaryExpression binaryExpression = new BinaryExpression(op, _leftExpression, _rightExpression);
			binaryExpression.OperatorMethod = binder.BindOperator(op, _leftExpression.ExpressionType, _rightExpression.ExpressionType);

			return binaryExpression;
		}
Esempio n. 14
0
		public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
		{
			bool isConjuctionOrDisjunction = expression.Op == BinaryOperator.LogicalAnd ||
			                                 expression.Op == BinaryOperator.LogicalOr;
			if (!isConjuctionOrDisjunction)
			{
				EmitCall(expression.OperatorMethod, null, expression.Left, expression.Right);
			}
			else
			{
				// He expression is a logical OR or a logical AND. In this case we have to pay
				// special attention to NULL values and short circuit evaluation.
				// Normally, a binary expression will yield NULL if any of the operands is NULL 
				// (as in function calls).
				//
				// For conjuctions and disjunctions this is not true. Sometimes these boolean
				// operators will return TRUE or FALSE though an operand was null. The following 
				// truth table must hold:
				//
				//    AND | F | T | N        OR | F | T | N
				//    ----+---+---+--        ---+---+---+--
				//    F   | F | F | F        F  | F | T | N
				//    T   | F | T | N        T  | T | T | T
				//    N   | F | N | N        N  | N | T | N
				//
				// In short, these exceptions exist:
				//
				// NULL AND FALSE ---> FALSE
				// FALSE AND NULL ---> FALSE
				//
				// NULL OR TRUE ---> TRUE
				// TRUE OR NULL ---> TRUE
				//
				// In addition we want to support short circuit evaluation.

				int left = DeclareLocal();
				int right = DeclareLocal();
				Label finish = _ilEmitContext.ILGenerator.DefineLabel();

				if (expression.Op == BinaryOperator.LogicalAnd)
				{
					// Peseudo code:
					//
					//	object left = expression.Left.Evaluate();
					//
					//	if (left != null && (bool)left == false)
					//		return false;
					//	else
					//	{
					//		object right = expression.Right.Evaluate();
					//
					//		if (right != null && (bool)right == false)
					//			return false;
					//
					//		if (rigth == null || left == null)
					//			return null;
					//
					//		return (bool)left & (bool)right;
					//	}

					Label checkRightSide = _ilEmitContext.ILGenerator.DefineLabel();
					Label checkAnyNull = _ilEmitContext.ILGenerator.DefineLabel();
					Label returnNull = _ilEmitContext.ILGenerator.DefineLabel();
					Label checkBothTrue = _ilEmitContext.ILGenerator.DefineLabel();

					VisitExpression(expression.Left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, checkRightSide);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brtrue, checkRightSide);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldc_I4_0);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Box, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);

					_ilEmitContext.ILGenerator.MarkLabel(checkRightSide);					
					VisitExpression(expression.Right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, checkAnyNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brtrue, checkAnyNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldc_I4_0);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Box, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);

					_ilEmitContext.ILGenerator.MarkLabel(checkAnyNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, returnNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brtrue, checkBothTrue);
					_ilEmitContext.ILGenerator.MarkLabel(returnNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);

					_ilEmitContext.ILGenerator.MarkLabel(checkBothTrue);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.And);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Box, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);
				}
				else
				{
					// Peseudo code:
					//
					//	object left = expression.Left.Evaluate();
					//
					//	if (left != null && (bool)left == true)
					//		return true;
					//	else
					//	{
					//		object right = expression.Right.Evaluate();
					//
					//		if (right != null && (bool)right == true)
					//			return true;
					//
					//		if (rigth == null || left == null)
					//			return null;
					//
					//		return (bool)left | (bool)right;
					//	}

					Label checkRightSide = _ilEmitContext.ILGenerator.DefineLabel();
					Label checkAnyNull = _ilEmitContext.ILGenerator.DefineLabel();
					Label returnNull = _ilEmitContext.ILGenerator.DefineLabel();
					Label checkAnyTrue = _ilEmitContext.ILGenerator.DefineLabel();

					VisitExpression(expression.Left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, checkRightSide);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, checkRightSide);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldc_I4_1);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Box, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);

					_ilEmitContext.ILGenerator.MarkLabel(checkRightSide);
					VisitExpression(expression.Right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, checkAnyNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, checkAnyNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldc_I4_1);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Box, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);

					_ilEmitContext.ILGenerator.MarkLabel(checkAnyNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, returnNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Brtrue, checkAnyTrue);
					_ilEmitContext.ILGenerator.MarkLabel(returnNull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);

					_ilEmitContext.ILGenerator.MarkLabel(checkAnyTrue);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, left);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, right);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Unbox_Any, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Or);
					_ilEmitContext.ILGenerator.Emit(OpCodes.Box, typeof(Boolean));
					_ilEmitContext.ILGenerator.Emit(OpCodes.Br, finish);
				}

				_ilEmitContext.ILGenerator.MarkLabel(finish);
			}

			return expression;
		}
            public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
            {
                if (expression.Op == BinaryOperator.LogicalAnd)
                {
                    return base.VisitBinaryExpression(expression);
                }
                else if (expression.Op == BinaryOperator.Equal)
                {
                    RowBufferEntry[] leftRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Left);
                    RowBufferEntry[] rightRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Right);

                    if (leftRowBufferEntries.Length == 1 && rightRowBufferEntries.Length == 1)
                    {
                        RowBufferEntry leftRowBufferEntry = leftRowBufferEntries[0];
                        RowBufferEntry rightRowBufferEntry = rightRowBufferEntries[0];

                        if (leftRowBufferEntry != rightRowBufferEntry)
                        {
                            // Both expressions depend on extactly one row buffer entry but
                            // they are not refering to the same row buffer entry.

                            bool leftDependsOnLeft= ArrayHelpers.Contains(_leftDefinedEntries, leftRowBufferEntry);
                            bool rightDependsOnRight = ArrayHelpers.Contains(_rightDefinedEntries, rightRowBufferEntry);

                            bool leftDependsOnRight = ArrayHelpers.Contains(_rightDefinedEntries, leftRowBufferEntry);
                            bool rightDependsOnLeft = ArrayHelpers.Contains(_leftDefinedEntries, rightRowBufferEntry);

                            if (leftDependsOnRight && rightDependsOnLeft)
                            {
                                ExpressionNode oldLeft = expression.Left;
                                expression.Left = expression.Right;
                                expression.Right = oldLeft;
                                leftDependsOnLeft = true;
                                rightDependsOnRight = true;
                            }

                            if (leftDependsOnLeft && rightDependsOnRight)
                            {
                                _equalPredicates.Add(expression);
                                return LiteralExpression.FromBoolean(true);
                            }
                        }
                    }
                }

                return expression;
            }
Esempio n. 16
0
		private static bool VisitBinaryExpression(BinaryExpression node1, BinaryExpression node2)
		{
			return node2 != null &&
			       node1.Op == node2.Op &&
			       Visit(node1.Left, node2.Left) && Visit(node1.Right, node2.Right);
		}
Esempio n. 17
0
        public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
        {
            if (expression.Op != BinaryOperator.LogicalAnd &&
                expression.Op != BinaryOperator.LogicalOr)
                return base.VisitBinaryExpression(expression);

            if (expression.Op == BinaryOperator.LogicalAnd)
            {
                // AND

                expression.Left = VisitExpression(expression.Left);
                expression.Right = VisitExpression(expression.Right);

                return expression;
            }
            else
            {
                // OR

                AlgebraNode input = GetAndResetLastNode();
                _probingEnabledStack.Push(false);

                List<ExpressionNode> scalarOrParts = new List<ExpressionNode>();
                List<AlgebraNode> algebrizedOrParts = new List<AlgebraNode>();
                foreach (ExpressionNode orPart in AstUtil.SplitCondition(LogicalOperator.Or, expression))
                {
                    if (!AstUtil.ContainsSubselect(orPart))
                    {
                        scalarOrParts.Add(orPart);
                    }
                    else
                    {
                        ExpressionNode replacedOrPart = VisitExpression(orPart);
                        FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                        filterAlgebraNode.Input = GetAndResetLastNode();
                        filterAlgebraNode.Predicate = replacedOrPart;
                        algebrizedOrParts.Add(filterAlgebraNode);
                    }
                }

                if (scalarOrParts.Count > 0)
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.Or, scalarOrParts);
                    filterAlgebraNode.Input = CreateConstantScan();
                    algebrizedOrParts.Insert(0, filterAlgebraNode);
                }

                _probingEnabledStack.Pop();

                ConcatAlgebraNode concat = new ConcatAlgebraNode();
                concat.DefinedValues = new UnitedValueDefinition[0];
                concat.Inputs = algebrizedOrParts.ToArray();

                RowBufferEntry probeColumn = CreateProbeColumn();
                JoinAlgebraNode leftSemiJoinBetweenInputAndConcat = new JoinAlgebraNode();
                leftSemiJoinBetweenInputAndConcat.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin;
                leftSemiJoinBetweenInputAndConcat.PassthruPredicate = CurrentPassthruPredicate;
                leftSemiJoinBetweenInputAndConcat.ProbeBufferEntry = probeColumn;
                leftSemiJoinBetweenInputAndConcat.Left = input;
                leftSemiJoinBetweenInputAndConcat.Right = concat;
                SetLastAlgebraNode(leftSemiJoinBetweenInputAndConcat);
                return CreateProbeColumnRef(probeColumn);
            }
        }
Esempio n. 18
0
		public override ExpressionNode VisitBinaryExpression(BinaryExpression expression)
		{
			_xmlWriter.WriteStartElement("binaryExpression");
			_xmlWriter.WriteAttributeString("operator", expression.Op.TokenText);
			WriteTypeAttribute(expression.ExpressionType);

			Visit(expression.Left);
			Visit(expression.Right);

			_xmlWriter.WriteEndElement();
			return expression;
		}