/// <summary> /// This method extracts the property and the constant out of a binary expression /// </summary> /// <param name="myBinaryExpression">The binary expression</param> /// <param name="myTransactionToken">The current transaction token</param> /// <param name="mySecurityToken">The current security token</param> /// <param name="myProperty">The property out parameter</param> /// <param name="myConstant">The constant out parameter</param> private void FindPropertyAndConstant(BinaryExpression myBinaryExpression, Int64 myTransactionToken, SecurityToken mySecurityToken, out QueryPlanProperty myProperty, out ILiteralExpression myConstant) { if (myBinaryExpression.Left is PropertyExpression) { myProperty = GenerateQueryPlanProperty((PropertyExpression)myBinaryExpression.Left, myTransactionToken, mySecurityToken); myConstant = (ILiteralExpression)myBinaryExpression.Right; } else { myProperty = GenerateQueryPlanProperty((PropertyExpression)myBinaryExpression.Right, myTransactionToken, mySecurityToken); myConstant = (ILiteralExpression)myBinaryExpression.Left; } }
/// <summary> /// Generates an greater or equals than query plan /// </summary> /// <param name="myBinaryExpression">The binary expression that has to be transfered into a greater or equals than query plan</param> /// <param name="myIsLongRunning">Determines whether it is anticipated that the request could take longer</param> /// <param name="myTransactionToken">The current transaction token</param> /// <param name="mySecurityToken">The current security token</param> /// <returns>An greater or equals query plan</returns> private IQueryPlan GenerateGreaterOrEqualsThanPlan(BinaryExpression myBinaryExpression, bool myIsLongRunning, Int64 myTransactionToken, SecurityToken mySecurityToken) { //sth like User/Age = 10 QueryPlanProperty property; ILiteralExpression constant; FindPropertyAndConstant(myBinaryExpression, myTransactionToken, mySecurityToken, out property, out constant); //is there an index specified if (myBinaryExpression.ExpressionIndex != null && _indexManager != null) { return new QueryPlanGreaterOrEqualsWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager, myBinaryExpression.ExpressionIndex); } //is there an index on this property? else if (_indexManager != null && _indexManager.HasIndex(property.Property, mySecurityToken, myTransactionToken)) { return new QueryPlanGreaterOrEqualsWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager); } else { return new QueryPlanGreaterOrEqualsWithoutIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning); } }
private IQueryPlan GenerateInRangePlan(BinaryExpression myBinaryExpression, bool myIsLongRunning, Int64 myTransactionToken, SecurityToken mySecurityToken) { QueryPlanProperty property; RangeLiteralExpression constant; if (myBinaryExpression.Left is PropertyExpression) { property = GenerateQueryPlanProperty((PropertyExpression)myBinaryExpression.Left, myTransactionToken, mySecurityToken); constant = (RangeLiteralExpression)myBinaryExpression.Right; } else { property = GenerateQueryPlanProperty((PropertyExpression)myBinaryExpression.Right, myTransactionToken, mySecurityToken); constant = (RangeLiteralExpression)myBinaryExpression.Left; } //is there an index specified if (myBinaryExpression.ExpressionIndex != null && _indexManager != null) { return new QueryPlanInRangeWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager, myBinaryExpression.ExpressionIndex); } //is there an index on this property? else if (_indexManager != null && _indexManager.HasIndex(property.Property, mySecurityToken, myTransactionToken)) { return new QueryPlanInRangeWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager); } else { return new QueryPlanInRangeWithoutIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning); } }
/// <summary> /// Generats a like query plan /// </summary> /// <param name="myBinaryExpression">The binary expression that has to be transfered into a like query plan</param> /// <param name="myIsLongRunning">Determines whether it is anticipated that the request could take longer</param> /// <param name="myTransactionToken">The current transaction token</param> /// <param name="mySecurityToken">The current security token</param> /// <returns>A like query plan</returns> private IQueryPlan GenerateLikePlan(BinaryExpression myBinaryExpression, bool myIsLongRunning, Int64 myTransactionToken, SecurityToken mySecurityToken) { QueryPlanProperty property; ILiteralExpression constant; FindPropertyAndConstant(myBinaryExpression, myTransactionToken, mySecurityToken, out property, out constant); //check property if (property.Property.BaseType != typeof(String)) { throw new InvalidLikeOperationException( String.Format("The property {0} is not of type String.", property.Property.Name)); } //check constant if (!(constant.Value is String)) { throw new InvalidLikeOperationException( String.Format("There has to be a String (current: {0}) constant to create a regular expression for a Like operation.", constant.Value.GetType().Name)); } //is there an index specified if (myBinaryExpression.ExpressionIndex != null && _indexManager != null) { return new QueryPlanLikeWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager, myBinaryExpression.ExpressionIndex); } //is there an index on this property? else if (_indexManager != null && _indexManager.HasIndex(property.Property, mySecurityToken, myTransactionToken)) { return new QueryPlanLikeWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager); } else { return new QueryPlanLikeWithoutIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning); } }
/// <summary> /// Generates a plan for an OR operation /// </summary> /// <param name="myBinaryExpression">The binary expression that has to be transfered into an OR query plan</param> /// <param name="myIsLongRunning">Determines whether it is anticipated that the request could take longer</param> /// <param name="myTransactionToken">The current transaction token</param> /// <param name="mySecurityToken">The current security token</param> /// <returns>An OR query plan</returns> private IQueryPlan GenerateORPlan(BinaryExpression myBinaryExpression, bool myIsLongRunning, Int64 myTransaction, SecurityToken mySecurity) { var left = CreateQueryPlan(myBinaryExpression.Left, myIsLongRunning, myTransaction, mySecurity); var right = CreateQueryPlan(myBinaryExpression.Right, myIsLongRunning, myTransaction, mySecurity); return new QueryPlanORSequentiell(left, right, myIsLongRunning); }
/// <summary> /// Generats an equals query plan /// </summary> /// <param name="myBinaryExpression">The binary expression that has to be transfered into an equals query plan</param> /// <param name="myIsLongRunning">Determines whether it is anticipated that the request could take longer</param> /// <param name="myTransactionToken">The current transaction token</param> /// <param name="mySecurityToken">The current security token</param> /// <returns>An equals query plan</returns> private IQueryPlan GenerateEqualsPlan(BinaryExpression myBinaryExpression, Boolean myIsLongRunning, Int64 myTransactionToken, SecurityToken mySecurityToken) { //it is not possible to have something complex (User.Age = Car.HorsePower) here --> filtered by validate of IExpression #region simple //sth like User/Age = 10 QueryPlanProperty property; ILiteralExpression constant; FindPropertyAndConstant(myBinaryExpression, myTransactionToken, mySecurityToken, out property, out constant); //is there an index specified if (myBinaryExpression.ExpressionIndex != null && _indexManager != null) { return new QueryPlanEqualsWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager, myBinaryExpression.ExpressionIndex); } //is there an index on this property? else if (_indexManager != null && _indexManager.HasIndex(property.Property, mySecurityToken, myTransactionToken)) { return new QueryPlanEqualsWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager); } else { return new QueryPlanEqualsWithoutIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning); } #endregion }
/// <summary> /// Generates a query plan from a binary expression /// </summary> /// <param name="binaryExpression">The binary expression</param> /// <param name="myIsLongRunning">Determines whether it is anticipated that the request could take longer</param> /// <param name="myTransactionToken">The current transaction token</param> /// <param name="mySecurityToken">The current security token</param> /// <returns>A query plan</returns> private IQueryPlan GenerateFromBinaryExpression(BinaryExpression myBinaryExpression, Boolean myIsLongRunning, Int64 myTransactionToken, SecurityToken mySecurityToken) { switch (myBinaryExpression.Operator) { #region Comparative case BinaryOperator.Equals: return GenerateEqualsPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.GreaterOrEqualsThan: return GenerateGreaterOrEqualsThanPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.GreaterThan: return GenerateGreaterThanPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.InRange: return GenerateInRangePlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.LessOrEqualsThan: return GenerateLessOrEqualsThanPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.LessThan: return GenerateLessThanPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.NotEquals: return GenerateNotEqualsPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.Like: return GenerateLikePlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); #endregion #region Logic case BinaryOperator.AND: return GenerateANDPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); case BinaryOperator.OR: return GenerateORPlan(myBinaryExpression, myIsLongRunning, myTransactionToken, mySecurityToken); #endregion default: throw new ArgumentOutOfRangeException(); } throw new NotImplementedException(); }
private bool IsValidExpressionIndex(BinaryExpression myBinaryExpression) { return myBinaryExpression.ExpressionIndex != null ? _indexManager.HasIndex(myBinaryExpression.ExpressionIndex) : true; }
/// <summary> /// Is this binary expression valid /// </summary> /// <param name="binaryExpression">The to be validated binary expression</param> /// <returns>True or false</returns> private bool IsValidBinaryExpression(BinaryExpression myBinaryExpression) { switch (myBinaryExpression.Operator) { #region comparative case BinaryOperator.Equals: case BinaryOperator.Like: case BinaryOperator.GreaterOrEqualsThan: case BinaryOperator.GreaterThan: case BinaryOperator.LessOrEqualsThan: case BinaryOperator.LessThan: case BinaryOperator.NotEquals: if (myBinaryExpression.Left.TypeOfExpression == TypeOfExpression.Property) { return myBinaryExpression.Right.TypeOfExpression == TypeOfExpression.Constant && IsValidExpressionIndex(myBinaryExpression); } else { return myBinaryExpression.Left.TypeOfExpression == TypeOfExpression.Constant && myBinaryExpression.Right.TypeOfExpression == TypeOfExpression.Property && IsValidExpressionIndex(myBinaryExpression); } case BinaryOperator.InRange: if (myBinaryExpression.Left.TypeOfExpression == TypeOfExpression.Property) { return myBinaryExpression.Right.TypeOfExpression == TypeOfExpression.Constant && myBinaryExpression.Right is RangeLiteralExpression && IsValidExpressionIndex(myBinaryExpression); } else { return (myBinaryExpression.Left.TypeOfExpression == TypeOfExpression.Constant && myBinaryExpression.Left is RangeLiteralExpression) && myBinaryExpression.Right.TypeOfExpression == TypeOfExpression.Property && IsValidExpressionIndex(myBinaryExpression); } #endregion #region logic case BinaryOperator.AND: case BinaryOperator.OR: return IsValidExpression(myBinaryExpression.Left) && IsValidExpression(myBinaryExpression.Right) && myBinaryExpression.ExpressionIndex == null; #endregion default: break; } return false; }
/// <summary> /// Generats a not equals query plan /// </summary> /// <param name="binaryExpression">The binary expression that has to be transfered into a not equals query plan</param> /// <param name="myIsLongRunning">Determines whether it is anticipated that the request could take longer</param> /// <param name="myTransactionToken">The current transaction token</param> /// <param name="mySecurityToken">The current security token</param> /// <returns>A not equals query plan</returns> private IQueryPlan GenerateNotEqualsPlan(BinaryExpression binaryExpression, bool myIsLongRunning, Int64 myTransactionToken, SecurityToken mySecurityToken) { QueryPlanProperty property; ILiteralExpression constant; FindPropertyAndConstant(binaryExpression, myTransactionToken, mySecurityToken, out property, out constant); //is there an index on this property? if (_indexManager != null && _indexManager.HasIndex(property.Property, mySecurityToken, myTransactionToken)) { return new QueryPlanNotEqualsWithIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning, _indexManager); } else { return new QueryPlanNotEqualsWithoutIndex(mySecurityToken, myTransactionToken, property, constant, _vertexStore, myIsLongRunning); } }
internal ServiceBinaryExpression(BinaryExpression myExpression) { this.Left = ConvertHelper.ToServiceExpression(myExpression.Left); this.Right = ConvertHelper.ToServiceExpression(myExpression.Right); this.Operator = (ServiceBinaryOperator)myExpression.Operator; }