/// <summary> /// SoftCastOp: /// If the input is /// Ref - ask for all properties /// Entity, ComplexType - ask for the same properties I've been asked for /// Record - ask for all properties (Note: This should be more optimized in the future /// since we can actually "remap" the properties) /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(SoftCastOp op, Node n) { PropertyRefList childProps = null; if (md.TypeSemantics.IsReferenceType(op.Type)) { childProps = PropertyRefList.All; } else if (md.TypeSemantics.IsNominalType(op.Type)) { PropertyRefList myProps = m_nodePropertyRefMap[n]; childProps = myProps.Clone(); } else if (md.TypeSemantics.IsRowType(op.Type)) { // // Note: We should do a better job here (by translating // our PropertyRefs to the equivalent property refs on the child // childProps = PropertyRefList.All; } if (childProps != null) { AddPropertyRefs(n.Child0, childProps); } VisitChildren(n); }
public override void Visit(SoftCastOp op, Node n) { VisitScalarOpDefault(op, n); // [....] 9/21/06 - temporarily removing check here // because the assert wrongly fails in some cases where the types are promotable, // but the facets are not. Put this back when that issue is solved. // Assert(TypeSemantics.IsEquivalentOrPromotableTo(n.Child0.Op.Type, op.Type), "Illegal SoftCastOp: Cannot promote input type {0} to target type {1}", n.Child0.Op.Type.Identity, op.Type.Identity); }
public static bool TryTranslateOverGroupAggregateVar( System.Data.Entity.Core.Query.InternalTrees.Node subtree, bool isVarDefinition, Command command, GroupAggregateVarInfoManager groupAggregateVarInfoManager, out GroupAggregateVarInfo groupAggregateVarInfo, out System.Data.Entity.Core.Query.InternalTrees.Node templateNode, out bool isUnnested) { GroupAggregateVarComputationTranslator computationTranslator = new GroupAggregateVarComputationTranslator(command, groupAggregateVarInfoManager); System.Data.Entity.Core.Query.InternalTrees.Node n = subtree; SoftCastOp softCastOp1 = (SoftCastOp)null; if (n.Op.OpType == OpType.SoftCast) { softCastOp1 = (SoftCastOp)n.Op; n = n.Child0; } bool flag; if (n.Op.OpType == OpType.Collect) { templateNode = computationTranslator.VisitCollect(n); flag = true; } else { templateNode = computationTranslator.VisitNode(n); flag = false; } groupAggregateVarInfo = computationTranslator._targetGroupAggregateVarInfo; isUnnested = computationTranslator._isUnnested; if (computationTranslator._targetGroupAggregateVarInfo == null || templateNode == null) { return(false); } if (softCastOp1 != null) { SoftCastOp softCastOp2 = flag || !isVarDefinition && AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, computationTranslator._targetGroupAggregateVarInfo.GroupAggregateVar) ? command.CreateSoftCastOp(TypeHelpers.GetEdmType <CollectionType>(softCastOp1.Type).TypeUsage) : softCastOp1; templateNode = command.CreateNode((Op)softCastOp2, templateNode); } return(true); }
public override void Visit(SoftCastOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { PropertyRefList propertyRefs = (PropertyRefList)null; if (TypeSemantics.IsReferenceType(op.Type)) { propertyRefs = PropertyRefList.All; } else if (TypeSemantics.IsNominalType(op.Type)) { propertyRefs = this.m_nodePropertyRefMap[n].Clone(); } else if (TypeSemantics.IsRowType(op.Type)) { propertyRefs = PropertyRefList.All; } if (propertyRefs != null) { this.AddPropertyRefs(n.Child0, propertyRefs); } this.VisitChildren(n); }
public override Node Visit(SoftCastOp op, Node n) { var inputTypeUsage = n.Child0.Op.Type; var oldType = op.Type; // Always think of your children first VisitChildren(n); var newType = GetNewType(oldType); if (md.TypeSemantics.IsRowType(oldType)) { PlanCompiler.Assert( n.Child0.Op.OpType == OpType.NewRecord, "Expected a record constructor here. Found " + n.Child0.Op.OpType + " instead"); var inputTypeInfo = m_typeInfo.GetTypeInfo(inputTypeUsage); var outputTypeInfo = m_typeInfo.GetTypeInfo(op.Type); var newOp = m_command.CreateNewRecordOp(newType); var newArgs = new List<Node>(); // We have to adjust for when we're supposed to add/remove null sentinels; // it is entirely possible that we may need to add multiple null sentinel // columns (See SQLBUDT #549068 for an example). IEnumerator<md.EdmProperty> outputs = newOp.Properties.GetEnumerator(); var outputPropertyCount = newOp.Properties.Count; outputs.MoveNext(); IEnumerator<Node> inputs = n.Child0.Children.GetEnumerator(); var inputPropertyCount = n.Child0.Children.Count; inputs.MoveNext(); // We know that all Null Sentinels are added on the left side, so we'll // just keep adding them until we have the same number of properties on // both the input and the output... while (inputPropertyCount < outputPropertyCount) { PlanCompiler.Assert( outputTypeInfo.HasNullSentinelProperty && !inputTypeInfo.HasNullSentinelProperty, "NullSentinelProperty mismatch on input?"); // make up a null sentinel; the output requires it. newArgs.Add(CreateNullSentinelConstant()); outputs.MoveNext(); outputPropertyCount--; } // Likewise, we'll just drop any null sentinel columns from the input until // we have the same number of columns... while (inputPropertyCount > outputPropertyCount) { PlanCompiler.Assert( !outputTypeInfo.HasNullSentinelProperty && inputTypeInfo.HasNullSentinelProperty, "NullSentinelProperty mismatch on output?"); // remove the null sentinel; the output doesn't require it. inputs.MoveNext(); inputPropertyCount--; } do { var p = outputs.Current; var arg = BuildSoftCast(inputs.Current, md.Helper.GetModelTypeUsage(p)); newArgs.Add(arg); outputs.MoveNext(); } while (inputs.MoveNext()); var newNode = m_command.CreateNode(newOp, newArgs); return newNode; } else if (md.TypeSemantics.IsCollectionType(oldType)) { // // Our collection type may have changed - 'coz the // element type of the collection may have changed. // Simply build up a new castOp (if necessary) // return BuildSoftCast(n.Child0, newType); } else if (md.TypeSemantics.IsPrimitiveType(oldType)) { // How primitive! Well, the Prime Directive prohibits me // from doing much with these. return n; } else { PlanCompiler.Assert( md.TypeSemantics.IsNominalType(oldType) || md.TypeSemantics.IsReferenceType(oldType), "Gasp! Not a nominal type or even a reference type"); // I'm dealing with a nominal type (entity, complex type) or // a reference type here. Every type in the same hierarchy // must have been rationalized into the same type, and so, we // won't need to do anything special PlanCompiler.Assert( Command.EqualTypes(newType, n.Child0.Op.Type), "Types are not equal"); return n.Child0; } }
public override void Visit(SoftCastOp op, Node n) { VisitScalarOpDefault(op, n); // Aconrad 9/21/06 - temporarily removing check here // because the assert wrongly fails in some cases where the types are promotable, // but the facets are not. Put this back when that issue is solved. // Assert(TypeSemantics.IsEquivalentOrPromotableTo(n.Child0.Op.Type, op.Type), "Illegal SoftCastOp: Cannot promote input type {0} to target type {1}", n.Child0.Op.Type.Identity, op.Type.Identity); }
/// <summary> /// Copies a SoftCastOp /// </summary> /// <param name="op">The Op to Copy</param> /// <param name="n">The Node that references the Op</param> /// <returns>A copy of the original Node that references a copy of the original Op</returns> public override Node Visit(SoftCastOp op, Node n) { return(CopyDefault(m_destCmd.CreateSoftCastOp(op.Type), n)); }
/// <summary> /// Visitor pattern method for SoftCastOp /// </summary> /// <param name="op"> The SoftCastOp being visited </param> /// <param name="n"> The Node that references the Op </param> public virtual void Visit(SoftCastOp op, Node n) { VisitScalarOpDefault(op, n); }
/// <summary> /// SoftCastOp: /// If the input is /// Ref - ask for all properties /// Entity, ComplexType - ask for the same properties I've been asked for /// Record - ask for all properties (Note: This should be more optimized in the future /// since we can actually "remap" the properties) /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> public override void Visit(SoftCastOp op, Node n) { PropertyRefList childProps = null; if (md.TypeSemantics.IsReferenceType(op.Type)) { childProps = PropertyRefList.All; } else if (md.TypeSemantics.IsNominalType(op.Type)) { var myProps = m_nodePropertyRefMap[n]; childProps = myProps.Clone(); } else if (md.TypeSemantics.IsRowType(op.Type)) { // // Note: We should do a better job here (by translating // our PropertyRefs to the equivalent property refs on the child // childProps = PropertyRefList.All; } if (childProps != null) { AddPropertyRefs(n.Child0, childProps); } VisitChildren(n); }
// <summary> // Try to produce an equivalent tree to the input subtree, over a single group aggregate variable. // Such translation can only be produced if all external references of the input subtree are to a // single group aggregate var, or to vars that are can be translated over that single group // aggregate var // </summary> // <param name="subtree"> The input subtree </param> // <param name="groupAggregateVarInfo"> The groupAggregateVarInfo over which the input subtree can be translated </param> // <param name="templateNode"> A tree that is equvalent to the input tree, but over the group aggregate variable represented by the groupAggregetVarInfo </param> // <returns> True, if the translation can be done, false otherwise </returns> public static bool TryTranslateOverGroupAggregateVar( Node subtree, bool isVarDefinition, Command command, GroupAggregateVarInfoManager groupAggregateVarInfoManager, out GroupAggregateVarInfo groupAggregateVarInfo, out Node templateNode, out bool isUnnested) { var handler = new GroupAggregateVarComputationTranslator(command, groupAggregateVarInfoManager); var inputNode = subtree; SoftCastOp softCastOp = null; bool isCollect; if (inputNode.Op.OpType == OpType.SoftCast) { softCastOp = (SoftCastOp)inputNode.Op; inputNode = inputNode.Child0; } if (inputNode.Op.OpType == OpType.Collect) { templateNode = handler.VisitCollect(inputNode); isCollect = true; } else { templateNode = handler.VisitNode(inputNode); isCollect = false; } groupAggregateVarInfo = handler._targetGroupAggregateVarInfo; isUnnested = handler._isUnnested; if (handler._targetGroupAggregateVarInfo == null || templateNode == null) { return(false); } if (softCastOp != null) { SoftCastOp newSoftCastOp; // // The type needs to be fixed only if the unnesting happened during this translation. // That can be recognized by these two cases: // 1) if the input node was a collect, or // 2) if the input did not represent a var definition, but a function aggregate argument and // the template is VarRef of a group aggregate var. // if (isCollect || !isVarDefinition && AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, handler._targetGroupAggregateVarInfo.GroupAggregateVar)) { newSoftCastOp = command.CreateSoftCastOp(TypeHelpers.GetEdmType <CollectionType>(softCastOp.Type).TypeUsage); } else { newSoftCastOp = softCastOp; } templateNode = command.CreateNode(newSoftCastOp, templateNode); } return(true); }
// <summary> // Copies a SoftCastOp // </summary> // <param name="op"> The Op to Copy </param> // <param name="n"> The Node that references the Op </param> // <returns> A copy of the original Node that references a copy of the original Op </returns> public override Node Visit(SoftCastOp op, Node n) { return CopyDefault(m_destCmd.CreateSoftCastOp(op.Type), n); }