Esempio n. 1
0
 protected override void VisitScalarOpDefault(ScalarOp op, Node n)
 {
     using (new AutoString(this, op)) {
         string separator = string.Empty;
         foreach (Node chi in n.Children)
         {
             WriteString(separator);
             VisitNode(chi);
             separator = ",";
         }
     }
 }
Esempio n. 2
0
 protected override void VisitScalarOpDefault(ScalarOp op, Node n)
 {
     VisitDefault(n);
     Assert(op.Type != null, "ScalarOp {0} with no datatype!", op.OpType);
     if (op.OpType != OpType.Element &&
         op.OpType != OpType.Exists &&
         op.OpType != OpType.Collect)
     {
         foreach (Node chi in n.Children)
         {
             AssertScalarOp(chi.Op);
         }
     }
 }
        /// <summary>
        /// Flattens out a constructor into a "flat" record constructor. 
        /// The "flat" record type is looked up for the current constructor's type,
        /// and each property is filled out from the current constructor's fields
        /// </summary>
        /// <param name="op">The NewRecordOp/NewInstanceOp</param>
        /// <param name="n">The current subtree</param>
        /// <returns>the new subtree</returns>
        private Node FlattenConstructor(ScalarOp op, Node n)
        {
            PlanCompiler.Assert(op.OpType == OpType.NewInstance || op.OpType == OpType.NewRecord || op.OpType == OpType.DiscriminatedNewEntity || op.OpType == OpType.NewEntity,
                "unexpected op: " + op.OpType + "?");

            // First visit all my children
            VisitChildren(n);

            // Find the new type corresponding to the type
            TypeInfo typeInfo = m_typeInfo.GetTypeInfo(op.Type);
            md.RowType flatType = typeInfo.FlattenedType;
            NewEntityBaseOp newEntityOp = op as NewEntityBaseOp;

            // Identify the fields
            IEnumerable opFields = null;
            DiscriminatedNewEntityOp discriminatedNewInstanceOp = null;
            if (op.OpType == OpType.NewRecord)
            {
                // Get only those fields that I have values for 
                opFields = ((NewRecordOp)op).Properties;
            }
            else if (op.OpType == OpType.DiscriminatedNewEntity)
            {
                // Get all properties projected by the discriminated new instance op
                discriminatedNewInstanceOp = (DiscriminatedNewEntityOp)op;
                opFields = discriminatedNewInstanceOp.DiscriminatorMap.Properties;
            }
            else
            {
                // Children align with structural members of type for a standard NewInstanceOp
                opFields = TypeHelpers.GetAllStructuralMembers(op.Type);
            }

            // Next, walk through each of my field, and flatten out any field
            // that is structured.
            List<md.EdmProperty> newFields = new List<md.EdmProperty>();
            List<Node> newFieldValues = new List<Node>();

            //
            // NOTE: we expect the type id property and the entityset id properties
            //       to be at the start of the properties collection.
            //
            // Add a typeid property if we need one
            //
            if (typeInfo.HasTypeIdProperty)
            {
                newFields.Add(typeInfo.TypeIdProperty);
                if (null == discriminatedNewInstanceOp)
                {
                    newFieldValues.Add(CreateTypeIdConstant(typeInfo));
                }
                else
                {
                    // first child in DiscriminatedNewInstanceOp is discriminator/typeid
                    Node discriminator = n.Children[0];

                    if (null == typeInfo.RootType.DiscriminatorMap)
                    {
                        // if there are multiple sets (or free-floating constructors) for this type
                        // hierarchy, normalize the discriminator value to expose the standard
                        // '0X' style values
                        discriminator = NormalizeTypeDiscriminatorValues(discriminatedNewInstanceOp, discriminator);
                    }

                    newFieldValues.Add(discriminator);
                }
            }

            //
            // Add an entitysetid property if we need one
            //
            if (typeInfo.HasEntitySetIdProperty)
            {
                newFields.Add(typeInfo.EntitySetIdProperty);

                PlanCompiler.Assert(newEntityOp != null, "unexpected optype:" + op.OpType);
                Node entitySetIdNode = GetEntitySetIdExpr(typeInfo.EntitySetIdProperty, newEntityOp);

                // Get the entity-set-id of the "current" entityset
                newFieldValues.Add(entitySetIdNode);
            }

            // Add a nullability property if we need one
            if (typeInfo.HasNullSentinelProperty)
            {
                newFields.Add(typeInfo.NullSentinelProperty);
                newFieldValues.Add(CreateNullSentinelConstant());
            }

            //
            // first child of discriminatedNewInstanceOp is the typeId; otherwise, the first child is the first property
            //
            int childrenIndex = null == discriminatedNewInstanceOp ? 0 : 1;

            foreach (md.EdmMember opField in opFields)
            {
                Node fieldValue = n.Children[childrenIndex];
                if (TypeUtils.IsStructuredType(md.Helper.GetModelTypeUsage(opField)))
                {
                    // Flatten out nested type
                    md.RowType nestedFlatType = m_typeInfo.GetTypeInfo(md.Helper.GetModelTypeUsage(opField)).FlattenedType;

                    // Find offset of opField in top-level flat type
                    int nestedPropertyOffset = typeInfo.RootType.GetNestedStructureOffset(new SimplePropertyRef(opField));

                    foreach (md.EdmProperty nestedProperty in nestedFlatType.Properties)
                    {
                        // Try to build up an accessor for this property from the input
                        Node nestedPropertyValue = BuildAccessor(fieldValue, nestedProperty);

                        if (null != nestedPropertyValue)
                        {
                            newFields.Add(flatType.Properties[nestedPropertyOffset]);
                            newFieldValues.Add(nestedPropertyValue);
                        }

                        nestedPropertyOffset++;
                    }
                }
                else
                {
                    PropertyRef propRef = new SimplePropertyRef(opField);
                    md.EdmProperty outputTypeProp = typeInfo.GetNewProperty(propRef);

                    newFields.Add(outputTypeProp);

                    newFieldValues.Add(fieldValue);
                }

                childrenIndex++;
            }

            //
            // We've now handled all the regular properties. Now, walk through all the rel properties - 
            // obviously, this only applies for the *NewEntityOps
            //
            if (newEntityOp != null)
            {
                foreach (RelProperty relProp in newEntityOp.RelationshipProperties)
                {
                    Node fieldValue = n.Children[childrenIndex];
                    md.RowType nestedFlatType = m_typeInfo.GetTypeInfo(relProp.ToEnd.TypeUsage).FlattenedType;

                    // Find offset of opField in top-level flat type
                    int nestedPropertyOffset = typeInfo.RootType.GetNestedStructureOffset(new RelPropertyRef(relProp));

                    foreach (md.EdmProperty nestedProperty in nestedFlatType.Properties)
                    {
                        // Try to build up an accessor for this property from the input
                        Node nestedPropertyValue = BuildAccessor(fieldValue, nestedProperty);

                        if (null != nestedPropertyValue)
                        {
                            newFields.Add(flatType.Properties[nestedPropertyOffset]);
                            newFieldValues.Add(nestedPropertyValue);
                        }

                        nestedPropertyOffset++;
                    }
                    childrenIndex++;
                }
            }

            //
            // So, now we have the list of all fields that should make up the 
            // flat type.  Create a new node with them.
            //
            NewRecordOp newOp = m_command.CreateNewRecordOp(typeInfo.FlattenedTypeUsage, newFields);
            Node newNode = m_command.CreateNode(newOp, newFieldValues);

            return newNode;
        }
        /// <summary>
        /// GetEntityKeyOp/GetRefKeyOp common handling
        /// 
        /// In either case, get the "key" properties from the input entity/ref, and 
        /// build up a record constructor from these values
        /// </summary>
        /// <param name="op">the GetRefKey/GetEntityKey op</param>
        /// <param name="n">current subtree</param>
        /// <returns>new expression subtree</returns>
        private Node FlattenGetKeyOp(ScalarOp op, Node n)
        {
            PlanCompiler.Assert(op.OpType == OpType.GetEntityRef || op.OpType == OpType.GetRefKey, "Expecting GetEntityRef or GetRefKey ops");

            TypeInfo inputTypeInfo = m_typeInfo.GetTypeInfo(((ScalarOp)n.Child0.Op).Type);
            TypeInfo outputTypeInfo = m_typeInfo.GetTypeInfo(op.Type);

            // Visit the child - will flatten out the input ref/entity
            VisitChildren(n);

            // Get "key" properties (and the corresponding values) from the input
            List<md.EdmProperty> inputFieldTypes;
            List<Node> inputFieldValues;

            // Get the key properties for GetRefKey; get the Identity properties
            // for GetEntityRef
            if (op.OpType == OpType.GetRefKey)
            {
                GetPropertyValues(inputTypeInfo, OperationKind.GetKeys, n.Child0, false /* ignore missing props */, out inputFieldTypes, out inputFieldValues);
            }
            else
            {
                PlanCompiler.Assert(op.OpType == OpType.GetEntityRef,
                    "Expected OpType.GetEntityRef: Found " + op.OpType);
                GetPropertyValues(inputTypeInfo, OperationKind.GetIdentity, n.Child0, false, out inputFieldTypes, out inputFieldValues);
            }

            if (outputTypeInfo.HasNullSentinelProperty && !inputTypeInfo.HasNullSentinelProperty)
            {
                // Add a null sentinel column, the input doesn't have one but the output requires it.
                inputFieldValues.Insert(0, CreateNullSentinelConstant());
            }

            // create an appropriate record constructor
            List<md.EdmProperty> outputFieldTypes = new List<md.EdmProperty>(outputTypeInfo.FlattenedType.Properties);
            PlanCompiler.Assert(inputFieldValues.Count == outputFieldTypes.Count, "fieldTypes.Count mismatch?");

            NewRecordOp rec = m_command.CreateNewRecordOp(outputTypeInfo.FlattenedTypeUsage, outputFieldTypes);
            Node newNode = m_command.CreateNode(rec, inputFieldValues);
            return newNode;
        }
Esempio n. 5
0
        /// <summary>
        /// Default handler for scalar Ops. Simply traverses the children,
        /// and also identifies any structured types along the way
        /// </summary>
        /// <param name="op">the ScalarOp</param>
        /// <param name="n">current subtree</param>
        /// <returns>the possibly modified node</returns>
        protected override Node VisitScalarOpDefault(ScalarOp op, Node n)
        {
            VisitChildren(n); // visit my children

            // keep track of referenced types
            AddTypeReference(op.Type);

            return n;
        }
 protected override void VisitScalarOpDefault(ScalarOp op, Node n)
 {
     VisitDefault(n);
     Assert(op.Type != null, "ScalarOp {0} with no datatype!", op.OpType);
     if (op.OpType != OpType.Element &&
         op.OpType != OpType.Exists
         &&
         op.OpType != OpType.Collect)
     {
         foreach (var chi in n.Children)
         {
             AssertScalarOp(chi.Op);
         }
     }
 }
 protected virtual void VisitScalarOpDefault(ScalarOp op, Node n)
 {
     VisitDefault(n);
 }