/// <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);
        }
Example #2
0
 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);
 }
Example #3
0
        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);
        }
Example #4
0
        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);
 }
Example #7
0
 /// <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);
        }
Example #11
0
 // <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);
 }