internal DbIsOfExpression(DbExpressionKind isOfKind, TypeUsage booleanResultType, DbExpression argument, TypeUsage isOfType) : base(isOfKind, booleanResultType, argument) { Debug.Assert(DbExpressionKind.IsOf == this.ExpressionKind || DbExpressionKind.IsOfOnly == this.ExpressionKind, string.Format(CultureInfo.InvariantCulture, "Invalid DbExpressionKind used in DbIsOfExpression: {0}", Enum.GetName(typeof(DbExpressionKind), this.ExpressionKind))); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsOfExpression requires a Boolean result type"); this._ofType = isOfType; }
internal static bool SupportsCastToString(TypeUsage typeUsage) { return(TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.String) || TypeSemantics.IsNumericType(typeUsage) || TypeSemantics.IsBooleanType(typeUsage) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.DateTime) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.DateTimeOffset) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.Time) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.Guid)); }
internal virtual ConstantBaseOp CreateConstantOp(TypeUsage type, object value) { if (value == null) { return((ConstantBaseOp) new NullOp(type)); } if (TypeSemantics.IsBooleanType(type)) { return((ConstantBaseOp) new InternalConstantOp(type, value)); } return((ConstantBaseOp) new ConstantOp(type, value)); }
internal DbInExpression(TypeUsage booleanResultType, DbExpression item, DbExpressionList list) : base(DbExpressionKind.In, booleanResultType) { DebugCheck.NotNull(item); DebugCheck.NotNull(list); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbInExpression must have a Boolean result type"); Debug.Assert( list.All(e => TypeSemantics.IsEqual(e.ResultType, item.ResultType)), "DbInExpression requires the same result type for the input expressions"); _item = item; _list = list; }
internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape) : base(DbExpressionKind.Like, booleanResultType) { Debug.Assert(input != null, "DbLikeExpression argument cannot be null"); Debug.Assert(pattern != null, "DbLikeExpression pattern cannot be null"); Debug.Assert(escape != null, "DbLikeExpression escape cannot be null"); Debug.Assert(TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String), "DbLikeExpression argument must have a string result type"); Debug.Assert(TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String), "DbLikeExpression pattern must have a string result type"); Debug.Assert(TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String), "DbLikeExpression escape must have a string result type"); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type"); this._argument = input; this._pattern = pattern; this._escape = escape; }
internal DbComparisonExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpression left, DbExpression right) : base(kind, booleanResultType, left, right) { Debug.Assert(left != null, "DbComparisonExpression left cannot be null"); Debug.Assert(right != null, "DbComparisonExpression right cannot be null"); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbComparisonExpression result type must be a Boolean type"); Debug.Assert( DbExpressionKind.Equals == kind || DbExpressionKind.LessThan == kind || DbExpressionKind.LessThanOrEquals == kind || DbExpressionKind.GreaterThan == kind || DbExpressionKind.GreaterThanOrEquals == kind || DbExpressionKind.NotEquals == kind, "Invalid DbExpressionKind used in DbComparisonExpression: " + Enum.GetName(typeof(DbExpressionKind), kind) ); }
public override void Visit(CaseOp op, Node n) { VisitScalarOpDefault(op, n); Assert((n.Children.Count >= 3 && n.Children.Count % 2 == 1), "CaseOp: Expected odd number of arguments, and at least 3; found {0}", n.Children.Count); // Validate that each when statement is of type Boolean for (int i = 0; i < n.Children.Count - 1; i += 2) { Assert(TypeSemantics.IsBooleanType(n.Children[i].Op.Type), "Encountered a when node with a non-boolean return type"); } // Ensure that the then clauses, the else clause and the result type are all the same for (int i = 1; i < n.Children.Count - 1; i += 2) { AssertEqualTypes(n.Op.Type, n.Children[i].Op.Type); } AssertEqualTypes(n.Op.Type, n.Children[n.Children.Count - 1].Op.Type); }
internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape) : base(DbExpressionKind.Like, booleanResultType) { DebugCheck.NotNull(input); DebugCheck.NotNull(pattern); DebugCheck.NotNull(escape); Debug.Assert( TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String), "DbLikeExpression argument must have a string result type"); Debug.Assert( TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String), "DbLikeExpression pattern must have a string result type"); Debug.Assert( TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String), "DbLikeExpression escape must have a string result type"); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type"); _argument = input; _pattern = pattern; _escape = escape; }
internal DbIsNullExpression(TypeUsage booleanResultType, DbExpression arg) : base(DbExpressionKind.IsNull, booleanResultType, arg) { Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsNullExpression requires a Boolean result type"); }
private static DbExpression SimplifyNestedTphDiscriminator(DbExpression expression) { var entityProjection = (DbProjectExpression)expression; var booleanColumnFilter = (DbFilterExpression)entityProjection.Input.Expression; var rowProjection = (DbProjectExpression)booleanColumnFilter.Input.Expression; var discriminatorFilter = (DbFilterExpression)rowProjection.Input.Expression; var predicates = FlattenOr(booleanColumnFilter.Predicate).ToList(); var propertyPredicates = predicates.OfType <DbPropertyExpression>() .Where( px => px.Instance.ExpressionKind == DbExpressionKind.VariableReference && ((DbVariableReferenceExpression)px.Instance).VariableName == booleanColumnFilter.Input.VariableName) .ToList(); if (predicates.Count != propertyPredicates.Count) { return(null); } var predicateColumnNames = propertyPredicates.Select(px => px.Property.Name).ToList(); var discriminatorPredicates = new Dictionary <object, DbComparisonExpression>(); if (!TypeSemantics.IsEntityType(discriminatorFilter.Input.VariableType) || !TryMatchDiscriminatorPredicate(discriminatorFilter, (compEx, discValue) => discriminatorPredicates.Add(discValue, compEx))) { return(null); } var discriminatorProp = (EdmProperty)((DbPropertyExpression)(discriminatorPredicates.First().Value).Left).Property; var rowConstructor = (DbNewInstanceExpression)rowProjection.Projection; var resultRow = TypeHelpers.GetEdmType <RowType>(rowConstructor.ResultType); var inputPredicateMap = new Dictionary <string, DbComparisonExpression>(); var selectorPredicateMap = new Dictionary <string, DbComparisonExpression>(); var columnValues = new Dictionary <string, DbExpression>(rowConstructor.Arguments.Count); for (var idx = 0; idx < rowConstructor.Arguments.Count; idx++) { var propName = resultRow.Properties[idx].Name; var columnVal = rowConstructor.Arguments[idx]; if (predicateColumnNames.Contains(propName)) { if (columnVal.ExpressionKind != DbExpressionKind.Case) { return(null); } var casePredicate = (DbCaseExpression)columnVal; if (casePredicate.When.Count != 1 || !TypeSemantics.IsBooleanType(casePredicate.Then[0].ResultType) || !TypeSemantics.IsBooleanType(casePredicate.Else.ResultType) || casePredicate.Then[0].ExpressionKind != DbExpressionKind.Constant || casePredicate.Else.ExpressionKind != DbExpressionKind.Constant || (bool)((DbConstantExpression)casePredicate.Then[0]).Value != true || (bool)((DbConstantExpression)casePredicate.Else).Value) { return(null); } DbPropertyExpression comparedProp; object constValue; if ( !TryMatchPropertyEqualsValue( casePredicate.When[0], rowProjection.Input.VariableName, out comparedProp, out constValue) || comparedProp.Property != discriminatorProp || !discriminatorPredicates.ContainsKey(constValue)) { return(null); } inputPredicateMap.Add(propName, discriminatorPredicates[constValue]); selectorPredicateMap.Add(propName, (DbComparisonExpression)casePredicate.When[0]); } else { columnValues.Add(propName, columnVal); } } // Build a new discriminator-based filter that only includes the same rows allowed by the higher '_from0' column-based filter var newDiscriminatorPredicate = Helpers.BuildBalancedTreeInPlace( new List <DbExpression>(inputPredicateMap.Values), (left, right) => left.Or(right)); discriminatorFilter = discriminatorFilter.Input.Filter(newDiscriminatorPredicate); var entitySelector = (DbCaseExpression)entityProjection.Projection; var newWhens = new List <DbExpression>(entitySelector.When.Count); var newThens = new List <DbExpression>(entitySelector.Then.Count); for (var idx = 0; idx < entitySelector.When.Count; idx++) { var propWhen = (DbPropertyExpression)entitySelector.When[idx]; var entityThen = (DbNewInstanceExpression)entitySelector.Then[idx]; DbComparisonExpression discriminatorWhen; if (!selectorPredicateMap.TryGetValue(propWhen.Property.Name, out discriminatorWhen)) { return(null); } newWhens.Add(discriminatorWhen); var inputBoundEntityConstructor = ValueSubstituter.Substitute(entityThen, entityProjection.Input.VariableName, columnValues); newThens.Add(inputBoundEntityConstructor); } var newElse = ValueSubstituter.Substitute(entitySelector.Else, entityProjection.Input.VariableName, columnValues); var newEntitySelector = DbExpressionBuilder.Case(newWhens, newThens, newElse); DbExpression result = discriminatorFilter.BindAs(rowProjection.Input.VariableName).Project(newEntitySelector); return(result); }
private static DbExpression SimplifyNestedTphDiscriminator(DbExpression expression) { DbProjectExpression projectExpression = (DbProjectExpression)expression; DbFilterExpression booleanColumnFilter = (DbFilterExpression)projectExpression.Input.Expression; DbProjectExpression expression1 = (DbProjectExpression)booleanColumnFilter.Input.Expression; DbFilterExpression expression2 = (DbFilterExpression)expression1.Input.Expression; List <DbExpression> list1 = ViewSimplifier.FlattenOr(booleanColumnFilter.Predicate).ToList <DbExpression>(); List <DbPropertyExpression> list2 = list1.OfType <DbPropertyExpression>().Where <DbPropertyExpression>((Func <DbPropertyExpression, bool>)(px => { if (px.Instance.ExpressionKind == DbExpressionKind.VariableReference) { return(((DbVariableReferenceExpression)px.Instance).VariableName == booleanColumnFilter.Input.VariableName); } return(false); })).ToList <DbPropertyExpression>(); if (list1.Count != list2.Count) { return((DbExpression)null); } List <string> list3 = list2.Select <DbPropertyExpression, string>((Func <DbPropertyExpression, string>)(px => px.Property.Name)).ToList <string>(); Dictionary <object, DbComparisonExpression> discriminatorPredicates = new Dictionary <object, DbComparisonExpression>(); if (!TypeSemantics.IsEntityType(expression2.Input.VariableType) || !ViewSimplifier.TryMatchDiscriminatorPredicate(expression2, (Action <DbComparisonExpression, object>)((compEx, discValue) => discriminatorPredicates.Add(discValue, compEx)))) { return((DbExpression)null); } EdmProperty property1 = (EdmProperty)((DbPropertyExpression)discriminatorPredicates.First <KeyValuePair <object, DbComparisonExpression> >().Value.Left).Property; DbNewInstanceExpression projection1 = (DbNewInstanceExpression)expression1.Projection; RowType edmType = TypeHelpers.GetEdmType <RowType>(projection1.ResultType); Dictionary <string, DbComparisonExpression> dictionary1 = new Dictionary <string, DbComparisonExpression>(); Dictionary <string, DbComparisonExpression> dictionary2 = new Dictionary <string, DbComparisonExpression>(); Dictionary <string, DbExpression> propertyValues = new Dictionary <string, DbExpression>(projection1.Arguments.Count); for (int index = 0; index < projection1.Arguments.Count; ++index) { string name = edmType.Properties[index].Name; DbExpression dbExpression = projection1.Arguments[index]; if (list3.Contains(name)) { if (dbExpression.ExpressionKind != DbExpressionKind.Case) { return((DbExpression)null); } DbCaseExpression dbCaseExpression = (DbCaseExpression)dbExpression; if (dbCaseExpression.When.Count != 1 || !TypeSemantics.IsBooleanType(dbCaseExpression.Then[0].ResultType) || (!TypeSemantics.IsBooleanType(dbCaseExpression.Else.ResultType) || dbCaseExpression.Then[0].ExpressionKind != DbExpressionKind.Constant) || (dbCaseExpression.Else.ExpressionKind != DbExpressionKind.Constant || !(bool)((DbConstantExpression)dbCaseExpression.Then[0]).Value || (bool)((DbConstantExpression)dbCaseExpression.Else).Value)) { return((DbExpression)null); } DbPropertyExpression property2; object key; if (!ViewSimplifier.TryMatchPropertyEqualsValue(dbCaseExpression.When[0], expression1.Input.VariableName, out property2, out key) || property2.Property != property1 || !discriminatorPredicates.ContainsKey(key)) { return((DbExpression)null); } dictionary1.Add(name, discriminatorPredicates[key]); dictionary2.Add(name, (DbComparisonExpression)dbCaseExpression.When[0]); } else { propertyValues.Add(name, dbExpression); } } DbExpression predicate = Helpers.BuildBalancedTreeInPlace <DbExpression>((IList <DbExpression>) new List <DbExpression>((IEnumerable <DbExpression>)dictionary1.Values), (Func <DbExpression, DbExpression, DbExpression>)((left, right) => (DbExpression)left.Or(right))); DbFilterExpression input = expression2.Input.Filter(predicate); DbCaseExpression projection2 = (DbCaseExpression)projectExpression.Projection; List <DbExpression> dbExpressionList1 = new List <DbExpression>(projection2.When.Count); List <DbExpression> dbExpressionList2 = new List <DbExpression>(projection2.Then.Count); for (int index = 0; index < projection2.When.Count; ++index) { DbPropertyExpression propertyExpression = (DbPropertyExpression)projection2.When[index]; DbNewInstanceExpression instanceExpression = (DbNewInstanceExpression)projection2.Then[index]; DbComparisonExpression comparisonExpression; if (!dictionary2.TryGetValue(propertyExpression.Property.Name, out comparisonExpression)) { return((DbExpression)null); } dbExpressionList1.Add((DbExpression)comparisonExpression); DbExpression dbExpression = ViewSimplifier.ValueSubstituter.Substitute((DbExpression)instanceExpression, projectExpression.Input.VariableName, propertyValues); dbExpressionList2.Add(dbExpression); } DbExpression elseExpression = ViewSimplifier.ValueSubstituter.Substitute(projection2.Else, projectExpression.Input.VariableName, propertyValues); DbCaseExpression dbCaseExpression1 = DbExpressionBuilder.Case((IEnumerable <DbExpression>)dbExpressionList1, (IEnumerable <DbExpression>)dbExpressionList2, elseExpression); return((DbExpression)input.BindAs(expression1.Input.VariableName).Project((DbExpression)dbCaseExpression1)); }