public override void Visit(RelPropertyOp op, Node n) { VisitScalarOpDefault(op, n); Assert(m_command.IsRelPropertyReferenced(op.PropertyInfo), "no such rel property:", op.PropertyInfo); Assert( TypeSemantics.IsEntityType(n.Child0.Op.Type), "argument to RelPropertyOp must be an entity type. Found: ", n.Child0.Op.Type); }
// <summary> // Returns true if typeUsage type is valid for IS [NOT] NULL (expr) operator // </summary> internal static bool IsValidIsNullOpType(TypeUsage typeUsage) { return(TypeSemantics.IsReferenceType(typeUsage) || TypeSemantics.IsEntityType(typeUsage) || TypeSemantics.IsScalarType(typeUsage) || TypeSemantics.IsRowType(typeUsage)); }
private ColumnMap CreateStructuralColumnMap(TypeUsage type, string name) { TypeInfo typeInfo = this.m_typeInfo.GetTypeInfo(type); if (TypeSemantics.IsRowType(type)) { return((ColumnMap)this.CreateRecordColumnMap(typeInfo, name)); } if (TypeSemantics.IsReferenceType(type)) { return((ColumnMap)this.CreateRefColumnMap(typeInfo, name)); } if (typeInfo.HasTypeIdProperty) { return((ColumnMap)this.CreatePolymorphicColumnMap(typeInfo, name)); } if (TypeSemantics.IsComplexType(type)) { return((ColumnMap)this.CreateComplexTypeColumnMap(typeInfo, name, (ComplexTypeColumnMap)null, (Dictionary <object, TypedColumnMap>)null, (List <TypedColumnMap>)null)); } if (TypeSemantics.IsEntityType(type)) { return((ColumnMap)this.CreateEntityColumnMap(typeInfo, name, (EntityColumnMap)null, (Dictionary <object, TypedColumnMap>)null, (List <TypedColumnMap>)null, true)); } throw new NotSupportedException(type.Identity); }
private void ExplodeRootStructuredType(RootTypeInfo rootType) { if (rootType.FlattenedType != null) { return; } if (StructuredTypeInfo.NeedsTypeIdProperty((TypeInfo)rootType)) { rootType.AddPropertyRef((PropertyRef)TypeIdPropertyRef.Instance); if (rootType.DiscriminatorMap != null) { rootType.TypeIdKind = TypeIdKind.UserSpecified; rootType.TypeIdType = Helper.GetModelTypeUsage(rootType.DiscriminatorMap.DiscriminatorProperty); } else { rootType.TypeIdKind = TypeIdKind.Generated; rootType.TypeIdType = this.m_stringType; } } if (this.NeedsEntitySetIdProperty((TypeInfo)rootType)) { rootType.AddPropertyRef((PropertyRef)EntitySetIdPropertyRef.Instance); } if (this.NeedsNullSentinelProperty((TypeInfo)rootType)) { rootType.AddPropertyRef((PropertyRef)NullSentinelPropertyRef.Instance); } this.ExplodeRootStructuredTypeHelper((TypeInfo)rootType); if (TypeSemantics.IsEntityType(rootType.Type)) { this.AddRelProperties((TypeInfo)rootType); } this.CreateFlattenedRecordType(rootType); }
internal static DbExpression FindNavigationExpression(DbExpression expression, AliasGenerator aliasGenerator, out NavigationInfo navInfo) { Debug.Assert(TypeSemantics.IsCollectionType(expression.ResultType), "Non-collection input to projection?"); navInfo = null; TypeUsage elementType = ((CollectionType)expression.ResultType.EdmType).TypeUsage; if (!TypeSemantics.IsEntityType(elementType) && !TypeSemantics.IsReferenceType(elementType)) { return(expression); } RelationshipNavigationVisitor visitor = new RelationshipNavigationVisitor(aliasGenerator); DbExpression rewrittenExpression = visitor.Find(expression); if (!object.ReferenceEquals(expression, rewrittenExpression)) { Debug.Assert(visitor._original != null && visitor._rewritten != null, "Expression was rewritten but no navigation was found?"); navInfo = new NavigationInfo(visitor._original, visitor._rewritten); return(rewrittenExpression); } else { return(expression); } }
internal static bool IsValidInOpType(TypeUsage typeUsage) { if (!TypeSemantics.IsReferenceType(typeUsage) && !TypeSemantics.IsEntityType(typeUsage)) { return(TypeSemantics.IsScalarType(typeUsage)); } return(true); }
internal DbNewInstanceExpression(TypeUsage resultType, DbExpressionList attributeValues, System.Collections.ObjectModel.ReadOnlyCollection <DbRelatedEntityRef> relationships) : this(resultType, attributeValues) { Debug.Assert(TypeSemantics.IsEntityType(resultType), "An entity type is required to create a NewEntityWithRelationships expression"); Debug.Assert(relationships != null, "Related entity ref collection cannot be null"); this._relatedEntityRefs = (relationships.Count > 0 ? relationships : null); }
public override void Visit(DerefOp op, Node n) { VisitScalarOpDefault(op, n); Assert(TypeSemantics.IsEntityType(op.Type), "Expected an entity type. Found " + op.Type); Assert(TypeSemantics.IsReferenceType(n.Child0.Op.Type), "Expected a ref type. Found " + n.Child0.Op.Type); RefType r = n.Child0.Op.Type.EdmType as RefType; Assert(r.ElementType.EdmEquals(op.Type.EdmType), "Inconsistent types"); }
internal DbNewInstanceExpression( TypeUsage resultType, DbExpressionList attributeValues, ReadOnlyCollection <DbRelatedEntityRef> relationships) : this(resultType, attributeValues) { Debug.Assert( TypeSemantics.IsEntityType(resultType), "An entity type is required to create a NewEntityWithRelationships expression"); DebugCheck.NotNull(relationships); _relatedEntityRefs = (relationships.Count > 0 ? relationships : null); }
private void AssignTypeIds() { int num = 0; foreach (KeyValuePair <TypeUsage, TypeInfo> typeInfo in this.m_typeInfoMap) { if (typeInfo.Value.RootType.DiscriminatorMap != null) { EntityType edmType = (EntityType)typeInfo.Key.EdmType; typeInfo.Value.TypeId = typeInfo.Value.RootType.DiscriminatorMap.GetTypeId(edmType); } else if (typeInfo.Value.IsRootType && (TypeSemantics.IsEntityType(typeInfo.Key) || TypeSemantics.IsComplexType(typeInfo.Key))) { this.AssignRootTypeId(typeInfo.Value, string.Format((IFormatProvider)CultureInfo.InvariantCulture, "{0}X", (object)num)); ++num; } } }
private void CreateFlattenedRecordType(RootTypeInfo type) { bool flag = TypeSemantics.IsEntityType(type.Type) && type.ImmediateSubTypes.Count == 0; List <KeyValuePair <string, TypeUsage> > keyValuePairList = new List <KeyValuePair <string, TypeUsage> >(); HashSet <string> stringSet = new HashSet <string>(); int num = 0; foreach (PropertyRef propertyRef in type.PropertyRefList) { string key = (string)null; if (flag) { SimplePropertyRef simplePropertyRef = propertyRef as SimplePropertyRef; if (simplePropertyRef != null) { key = simplePropertyRef.Property.Name; } } if (key == null) { key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture); ++num; } while (stringSet.Contains(key)) { key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture); ++num; } TypeUsage propertyType = this.GetPropertyType(type, propertyRef); keyValuePairList.Add(new KeyValuePair <string, TypeUsage>(key, propertyType)); stringSet.Add(key); } type.FlattenedType = TypeHelpers.CreateRowType((IEnumerable <KeyValuePair <string, TypeUsage> >)keyValuePairList); IEnumerator <PropertyRef> enumerator = type.PropertyRefList.GetEnumerator(); foreach (EdmProperty property in type.FlattenedType.Properties) { if (!enumerator.MoveNext()) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(false, "property refs count and flattened type member count mismatch?"); } type.AddPropertyMapping(enumerator.Current, property); } }
internal static DbExpression FindNavigationExpression( DbExpression expression, AliasGenerator aliasGenerator, out ObjectSpanRewriter.NavigationInfo navInfo) { navInfo = (ObjectSpanRewriter.NavigationInfo)null; TypeUsage typeUsage = ((CollectionType)expression.ResultType.EdmType).TypeUsage; if (!TypeSemantics.IsEntityType(typeUsage) && !TypeSemantics.IsReferenceType(typeUsage)) { return(expression); } ObjectSpanRewriter.RelationshipNavigationVisitor navigationVisitor = new ObjectSpanRewriter.RelationshipNavigationVisitor(aliasGenerator); DbExpression dbExpression = navigationVisitor.Find(expression); if (object.ReferenceEquals((object)expression, (object)dbExpression)) { return(expression); } navInfo = new ObjectSpanRewriter.NavigationInfo(navigationVisitor._original, navigationVisitor._rewritten); return(dbExpression); }
public override void Visit(ComparisonOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { TypeUsage type = (n.Child0.Op as ScalarOp).Type; if (!TypeUtils.IsStructuredType(type)) { this.VisitChildren(n); } else if (TypeSemantics.IsRowType(type) || TypeSemantics.IsReferenceType(type)) { this.VisitDefault(n); } else { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsEntityType(type), "unexpected childOpType?"); PropertyRefList identityProperties = PropertyPushdownHelper.GetIdentityProperties(TypeHelpers.GetEdmType <EntityType>(type)); foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Children) { this.AddPropertyRefs(child, identityProperties); } this.VisitChildren(n); } }
/// <summary> /// Adds the flattened properties on the input to the flattenedProperties list. /// </summary> /// <param name="input"></param> /// <param name="flattenedProperties"></param> private void FlattenProperties(DbExpression input, IList <DbPropertyExpression> flattenedProperties) { IList <EdmProperty> properties = TypeHelpers.GetProperties(input.ResultType); Debug.Assert(properties.Count != 0, "No nested properties when FlattenProperties called?"); for (int i = 0; i < properties.Count; i++) { DbExpression propertyInput = input; DbPropertyExpression propertyExpression = propertyInput.Property(properties[i]); if (TypeSemantics.IsPrimitiveType(properties[i].TypeUsage)) { flattenedProperties.Add(propertyExpression); } else { Debug.Assert(TypeSemantics.IsEntityType(properties[i].TypeUsage) || TypeSemantics.IsRowType(properties[i].TypeUsage), "The input to FlattenProperties is not of EntityType or RowType?"); FlattenProperties(propertyExpression, flattenedProperties); } } }
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)); }
internal DbDerefExpression(TypeUsage entityResultType, DbExpression refExpr) : base(DbExpressionKind.Deref, entityResultType, refExpr) { Debug.Assert(TypeSemantics.IsEntityType(entityResultType), "DbDerefExpression requires an entity result type"); }
internal static bool IsStructuredType(TypeUsage type) { if (!TypeSemantics.IsReferenceType(type) && !TypeSemantics.IsRowType(type) && (!TypeSemantics.IsEntityType(type) && !TypeSemantics.IsRelationshipType(type))) { return(TypeSemantics.IsComplexType(type)); } return(true); }
internal NewInstanceOp(TypeUsage type) : base(OpType.NewInstance, type) { Debug.Assert(!type.EdmType.Abstract, "cannot create new instance of abstract type"); Debug.Assert(!TypeSemantics.IsEntityType(type), "cannot use this Op for entity construction"); }
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); }