/// <summary> /// Gets the list of "identity" properties for an entity. Gets the /// "entitysetid" property in addition to the "key" properties /// </summary> /// <param name="type"></param> /// <returns></returns> private static PropertyRefList GetIdentityProperties(md.EntityType type) { PropertyRefList desiredProperties = GetKeyProperties(type); desiredProperties.Add(EntitySetIdPropertyRef.Instance); return(desiredProperties); }
/// <summary> /// ComparisonOp handling /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(ComparisonOp op, Node n) { // Check to see if the children are structured types. Furthermore, // if the children are of entity types, then all we really need are // the key properties (and the entityset property) // For record and ref types, simply keep going md.TypeUsage childOpType = (n.Child0.Op as ScalarOp).Type; if (!TypeUtils.IsStructuredType(childOpType)) { VisitChildren(n); } else if (md.TypeSemantics.IsRowType(childOpType) || md.TypeSemantics.IsReferenceType(childOpType)) { VisitDefault(n); } else { PlanCompiler.Assert(md.TypeSemantics.IsEntityType(childOpType), "unexpected childOpType?"); PropertyRefList desiredProperties = GetIdentityProperties(TypeHelpers.GetEdmType <md.EntityType>(childOpType)); // Now push these set of properties to each child foreach (Node chi in n.Children) { AddPropertyRefs(chi, desiredProperties); } // Visit the children VisitChildren(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)) { 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); }
/// <summary> /// SetOp handling /// UnionAllOp handling /// IntersectOp handling /// ExceptOp handling /// /// Visitor for a SetOp. Pushes desired properties to the corresponding /// Vars of the input /// </summary> /// <param name="op">the setop</param> /// <param name="n"></param> protected override void VisitSetOp(SetOp op, Node n) { foreach (VarMap varMap in op.VarMap) { foreach (KeyValuePair <Var, Var> kv in varMap) { if (TypeUtils.IsStructuredType(kv.Key.Type)) { // Get the set of expected properties for the unionVar, and // push it down to the inputvars // For Intersect and ExceptOps, we need all properties // from the input // We call GetPropertyRefList() always to initialize // the map, even though we may not use it // PropertyRefList myProps = GetPropertyRefList(kv.Key); if (op.OpType == OpType.Intersect || op.OpType == OpType.Except) { myProps = PropertyRefList.All; // We "want" all properties even on the output of the setop AddPropertyRefs(kv.Key, myProps); } else { myProps = myProps.Clone(); } AddPropertyRefs(kv.Value, myProps); } } } VisitChildren(n); }
/// <summary> /// IsOfOp handling /// /// Simply requests the "typeid" property from /// the input. No other property is required /// </summary> /// <param name="op">IsOf op</param> /// <param name="n">Node to visit</param> public override void Visit(IsOfOp op, Node n) { // The only property I need from my child is the typeid property; PropertyRefList childProps = new PropertyRefList(); childProps.Add(TypeIdPropertyRef.Instance); AddPropertyRefs(n.Child0, childProps); VisitChildren(n); }
/// <summary> /// VarRefOp handling /// /// Simply passes along the current "desired" properties /// to the corresponding Var /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(VarRefOp op, Node n) { if (TypeUtils.IsStructuredType(op.Var.Type)) { // Get the properties that my parent expects from me. PropertyRefList myProps = GetPropertyRefList(n); // Add this onto the list of properties expected from the var itself AddPropertyRefs(op.Var, myProps); } }
/// <summary> /// VarDefOp handling /// /// Pushes the "desired" properties to the /// defining expression /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(VarDefOp op, Node n) { if (TypeUtils.IsStructuredType(op.Var.Type)) { PropertyRefList myProps = GetPropertyRefList(op.Var); // Push this down to the expression defining the var AddPropertyRefs(n.Child0, myProps); } VisitChildren(n); }
/// <summary> /// Create a clone of myself /// </summary> /// <returns>a clone of myself</returns> internal PropertyRefList Clone() { PropertyRefList newProps = new PropertyRefList(m_allProperties); foreach (PropertyRef p in this.m_propertyReferences.Keys) { newProps.Add(p); } return(newProps); }
/// <summary> /// Append an existing list of property references to myself /// </summary> /// <param name="propertyRefs">list of property references</param> internal void Append(PropertyRefList propertyRefs) { if (m_allProperties) { return; } foreach (var p in propertyRefs.m_propertyReferences.Keys) { Add(p); } }
/// <summary> /// Get the list of desired properties for a Var /// </summary> /// <param name="v">the var</param> /// <returns>List of desired properties</returns> private PropertyRefList GetPropertyRefList(Var v) { PropertyRefList propRefs; if (!m_varPropertyRefMap.TryGetValue(v, out propRefs)) { propRefs = new PropertyRefList(); m_varPropertyRefMap[v] = propRefs; } return(propRefs); }
/// <summary> /// Get the list of propertyrefs for a node. If none exists, create an /// empty structure and store it in the map /// </summary> /// <param name="node">Specific node</param> /// <returns>List of properties expected from this node</returns> private PropertyRefList GetPropertyRefList(Node node) { PropertyRefList propRefs; if (!m_nodePropertyRefMap.TryGetValue(node, out propRefs)) { propRefs = new PropertyRefList(); m_nodePropertyRefMap[node] = propRefs; } return(propRefs); }
/// <summary> /// Append an existing list of property references to myself /// </summary> /// <param name="propertyRefs">list of property references</param> internal void Append(PropertyRefList propertyRefs) { if (m_allProperties) { return; } foreach (PropertyRef p in propertyRefs.m_propertyReferences.Keys) { this.Add(p); } }
/// <summary> /// TreatOp handling /// /// Simply passes down "my" desired properties, and additionally /// asks for the TypeID property /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(TreatOp op, Node n) { // First find the properties that my parent expects from me PropertyRefList pdProps = GetPropertyRefList(n); // Push down each of these, and in addition, push down the typeid property // to my child PropertyRefList childProps = pdProps.Clone(); childProps.Add(TypeIdPropertyRef.Instance); AddPropertyRefs(n.Child0, childProps); VisitChildren(n); }
/// <summary> /// Gets the list of key properties for an entity /// </summary> /// <param name="entityType"></param> /// <returns></returns> private static PropertyRefList GetKeyProperties(md.EntityType entityType) { PropertyRefList desiredProperties = new PropertyRefList(); foreach (md.EdmMember p in entityType.KeyMembers) { md.EdmProperty edmP = p as md.EdmProperty; PlanCompiler.Assert(edmP != null, "EntityType had non-EdmProperty key member?"); SimplePropertyRef pRef = new SimplePropertyRef(edmP); desiredProperties.Add(pRef); } return(desiredProperties); }
/// <summary> /// ScanViewOp /// /// ask for all properties from the view definition /// that have currently been requested from the view itself /// </summary> /// <param name="op">current ScanViewOp</param> /// <param name="n">current node</param> public override void Visit(ScanViewOp op, Node n) { PlanCompiler.Assert(op.Table.Columns.Count == 1, "ScanViewOp with multiple columns?"); Var columnVar = op.Table.Columns[0]; PropertyRefList columnProps = GetPropertyRefList(columnVar); Var inputVar = NominalTypeEliminator.GetSingletonVar(n.Child0); PlanCompiler.Assert(inputVar != null, "cannot determine single Var from ScanViewOp's input"); AddPropertyRefs(inputVar, columnProps.Clone()); VisitChildren(n); }
/// <summary> /// GetEntityRefOp handling /// /// Ask for the "identity" properties from the input entity, and push that /// down to my child /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(GetEntityRefOp op, Node n) { ScalarOp childOp = n.Child0.Op as ScalarOp; PlanCompiler.Assert(childOp != null, "input to GetEntityRefOp is not a ScalarOp?"); // md.EntityType entityType = TypeHelpers.GetEdmType <md.EntityType>(childOp.Type); PropertyRefList desiredProperties = GetIdentityProperties(entityType); AddPropertyRefs(n.Child0, desiredProperties); VisitNode(n.Child0); }
/// <summary> /// CaseOp handling /// /// Pushes its desired properties to each of the WHEN/ELSE clauses /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(CaseOp op, Node n) { // First find the properties that my parent expects from me PropertyRefList pdProps = GetPropertyRefList(n); // push down the same properties to my then/else clauses. // the "when" clauses are irrelevant for (int i = 1; i < n.Children.Count - 1; i += 2) { PropertyRefList cdProps = pdProps.Clone(); AddPropertyRefs(n.Children[i], cdProps); } AddPropertyRefs(n.Children[n.Children.Count - 1], pdProps.Clone()); // Now visit the children VisitChildren(n); }
/// <summary> /// Common handler for RelPropertyOp and PropertyOp. /// Simply pushes down the desired set of properties to the child /// </summary> /// <param name="op">the *propertyOp</param> /// <param name="n">node tree corresponding to the Op</param> /// <param name="propertyRef">the property reference</param> private void VisitPropertyOp(Op op, Node n, PropertyRef propertyRef) { PropertyRefList cdProps = new PropertyRefList(); if (!TypeUtils.IsStructuredType(op.Type)) { cdProps.Add(propertyRef); } else { // Get the list of properties my parent expects from me. PropertyRefList pdProps = GetPropertyRefList(n); // Ask my child (which is really my container type) for each of these // properties // If I've been asked for all my properties, then get the // corresponding flat list of properties from my children. // For now, however, simply ask for all properties in this case // What we really need to do is to get the "flattened" list of // properties from the input, and prepend each of these with // our property name. We don't have that info available, so // I'm taking the easier route. if (pdProps.AllProperties) { cdProps = pdProps; } else { foreach (PropertyRef p in pdProps.Properties) { cdProps.Add(p.CreateNestedPropertyRef(propertyRef)); } } } // push down my expectations AddPropertyRefs(n.Child0, cdProps); VisitChildren(n); }
/// <summary> /// IsOfOp handling /// /// Simply requests the "typeid" property from /// the input. No other property is required /// </summary> /// <param name="op">IsOf op</param> /// <param name="n">Node to visit</param> public override void Visit(IsOfOp op, Node n) { // The only property I need from my child is the typeid property; PropertyRefList childProps = new PropertyRefList(); childProps.Add(TypeIdPropertyRef.Instance); AddPropertyRefs(n.Child0, childProps); VisitChildren(n); }
/// <summary> /// Get the list of desired properties for a Var /// </summary> /// <param name="v">the var</param> /// <returns>List of desired properties</returns> private PropertyRefList GetPropertyRefList(Var v) { PropertyRefList propRefs; if (!m_varPropertyRefMap.TryGetValue(v, out propRefs)) { propRefs = new PropertyRefList(); m_varPropertyRefMap[v] = propRefs; } return propRefs; }
/// <summary> /// Add a new set of properties to a Var /// </summary> /// <param name="v">the var</param> /// <param name="propertyRefs">desired properties</param> private void AddPropertyRefs(Var v, PropertyRefList propertyRefs) { PropertyRefList currentRefs = GetPropertyRefList(v); currentRefs.Append(propertyRefs); }
/// <summary> /// Create a clone of myself /// </summary> /// <returns>a clone of myself</returns> internal PropertyRefList Clone() { PropertyRefList newProps = new PropertyRefList(m_allProperties); foreach (PropertyRef p in this.m_propertyReferences.Keys) newProps.Add(p); return newProps; }
/// <summary> /// Add a list of property references for this node /// </summary> /// <param name="node">the node</param> /// <param name="propertyRefs">list of property references</param> private void AddPropertyRefs(Node node, PropertyRefList propertyRefs) { PropertyRefList refs = GetPropertyRefList(node); refs.Append(propertyRefs); }
/// <summary> /// Add a new set of properties to a Var /// </summary> /// <param name="v">the var</param> /// <param name="propertyRefs">desired properties</param> private void AddPropertyRefs(Var v, PropertyRefList propertyRefs) { PropertyRefList currentRefs = GetPropertyRefList(v); currentRefs.Append(propertyRefs); }
/// <summary> /// Common handler for RelPropertyOp and PropertyOp. /// Simply pushes down the desired set of properties to the child /// </summary> /// <param name="op">the *propertyOp</param> /// <param name="n">node tree corresponding to the Op</param> /// <param name="propertyRef">the property reference</param> private void VisitPropertyOp(Op op, Node n, PropertyRef propertyRef) { PropertyRefList cdProps = new PropertyRefList(); if (!TypeUtils.IsStructuredType(op.Type)) { cdProps.Add(propertyRef); } else { // Get the list of properties my parent expects from me. PropertyRefList pdProps = GetPropertyRefList(n); // Ask my child (which is really my container type) for each of these // properties // If I've been asked for all my properties, then get the // corresponding flat list of properties from my children. // For now, however, simply ask for all properties in this case // What we really need to do is to get the "flattened" list of // properties from the input, and prepend each of these with // our property name. We don't have that info available, so // I'm taking the easier route. if (pdProps.AllProperties) { cdProps = pdProps; } else { foreach (PropertyRef p in pdProps.Properties) { cdProps.Add(p.CreateNestedPropertyRef(propertyRef)); } } } // push down my expectations AddPropertyRefs(n.Child0, cdProps); VisitChildren(n); }
/// <summary> /// Create a clone of myself /// </summary> /// <returns>a clone of myself</returns> internal PropertyRefList Clone() { var newProps = new PropertyRefList(m_allProperties); foreach (var p in m_propertyReferences.Keys) { newProps.Add(p); } return newProps; }
/// <summary> /// Flattens a CaseOp - Specifically, if the CaseOp returns a structuredtype, /// then the CaseOp is broken up so that we build up a "flat" record constructor /// for that structured type, with each argument to the record constructor being /// a (scalar) CaseOp. For example: /// /// Case when b1 then e1 else e2 end /// /// gets translated into: /// /// RecordOp(case when b1 then e1.a else e2.a end, /// case when b1 then e1.b else e2.b end, /// ...) /// /// The property extraction is optimized by producing only those properties /// that have actually been requested. /// </summary> /// <param name="op">the CaseOp</param> /// <param name="n">Node corresponding to the CaseOp</param> /// <param name="typeInfo">Information about the type</param> /// <param name="desiredProperties">Set of properties desired</param> /// <returns></returns> private Node FlattenCaseOp(CaseOp op, Node n, TypeInfo typeInfo, PropertyRefList desiredProperties) { // Build up a type constructor - with only as many fields filled in // as are desired. List<md.EdmProperty> fieldTypes = new List<md.EdmProperty>(); List<Node> fieldValues = new List<Node>(); foreach (PropertyRef pref in typeInfo.PropertyRefList) { // Is this property desired later? if (!desiredProperties.Contains(pref)) { continue; } md.EdmProperty property = typeInfo.GetNewProperty(pref); // Build up an accessor for this property across each when/then clause List<Node> caseChildren = new List<Node>(); for (int i = 0; i < n.Children.Count - 1; ) { Node whenNode = Copy(n.Children[i]); caseChildren.Add(whenNode); i++; Node propNode = BuildAccessorWithNulls(n.Children[i], property); caseChildren.Add(propNode); i++; } Node elseNode = BuildAccessorWithNulls(n.Children[n.Children.Count - 1], property); caseChildren.Add(elseNode); Node caseNode = m_command.CreateNode(m_command.CreateCaseOp(md.Helper.GetModelTypeUsage(property)), caseChildren); fieldTypes.Add(property); fieldValues.Add(caseNode); } NewRecordOp newRec = m_command.CreateNewRecordOp(typeInfo.FlattenedTypeUsage, fieldTypes); return m_command.CreateNode(newRec, fieldValues); }
/// <summary> /// Get the list of propertyrefs for a node. If none exists, create an /// empty structure and store it in the map /// </summary> /// <param name="node">Specific node</param> /// <returns>List of properties expected from this node</returns> private PropertyRefList GetPropertyRefList(Node node) { PropertyRefList propRefs; if (!m_nodePropertyRefMap.TryGetValue(node, out propRefs)) { propRefs = new PropertyRefList(); m_nodePropertyRefMap[node] = propRefs; } return propRefs; }
/// <summary> /// Gets the list of key properties for an entity /// </summary> /// <param name="entityType"></param> /// <returns></returns> private static PropertyRefList GetKeyProperties(md.EntityType entityType) { PropertyRefList desiredProperties = new PropertyRefList(); foreach (md.EdmMember p in entityType.KeyMembers) { md.EdmProperty edmP = p as md.EdmProperty; PlanCompiler.Assert(edmP != null, "EntityType had non-EdmProperty key member?"); SimplePropertyRef pRef = new SimplePropertyRef(edmP); desiredProperties.Add(pRef); } return desiredProperties; }
/// <summary> /// Add a list of property references for this node /// </summary> /// <param name="node">the node</param> /// <param name="propertyRefs">list of property references</param> private void AddPropertyRefs(Node node, PropertyRefList propertyRefs) { PropertyRefList refs = GetPropertyRefList(node); refs.Append(propertyRefs); }
/// <summary> /// Append an existing list of property references to myself /// </summary> /// <param name="propertyRefs">list of property references</param> internal void Append(PropertyRefList propertyRefs) { if (m_allProperties) return; foreach (PropertyRef p in propertyRefs.m_propertyReferences.Keys) { this.Add(p); } }