1 //---------------------------------------------------------------------
2 // <copyright file="Nodes.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System.Collections.Generic;
12 using System.Data.Metadata.Edm;
13 using System.Globalization;
14 using System.Diagnostics;
16 namespace System.Data.Query.InternalTrees
19 /// A Node describes a node in a query tree. Each node has an operator, and
20 /// a list of zero or more children of that operator.
26 private List<Node> m_children;
28 private NodeInfo m_nodeInfo;
33 /// Basic constructor.
35 /// NEVER call this routine directly - you should always use the Command.CreateNode
38 /// <param name="nodeId">id for the node</param>
39 /// <param name="op">The operator</param>
40 /// <param name="children">List of child nodes</param>
41 internal Node(int nodeId, Op op, List<Node> children)
45 m_children = children;
49 /// This routine is only used for building up rule patterns.
50 /// NEVER use this routine for building up nodes in a user command tree.
52 /// <param name="op"></param>
53 /// <param name="children"></param>
54 internal Node(Op op, params Node[] children)
55 : this(-1, op, new List<Node>(children))
60 #region public properties and methods
63 internal int Id { get { return m_id; } }
67 /// Get the list of children
69 internal List<Node> Children { get { return m_children; } }
72 /// Gets or sets the node's operator
74 internal Op Op { get { return m_op; } set { m_op = value; } }
77 /// Simpler (?) getter/setter routines
79 internal Node Child0 { get { return m_children[0]; } set { m_children[0] = value; } }
81 /// Do I have a zeroth child?
83 internal bool HasChild0 { get { return m_children.Count > 0; } }
86 /// Get/set first child
88 internal Node Child1 { get { return m_children[1]; } set { m_children[1] = value; } }
90 /// Do I have a child1?
92 internal bool HasChild1 { get { return m_children.Count > 1; } }
95 /// get/set second child
97 internal Node Child2 { get { return m_children[2]; } set { m_children[2] = value; } }
99 /// get/set second child
101 internal Node Child3 { get { return m_children[3]; } /* commented out because of fxcop - there are no upstream callers -- set { m_children[3] = value; }*/ }
103 /// Do I have a child2 (third child really)
105 internal bool HasChild2 { get { return m_children.Count > 2; } }
107 /// Do I have a child3 (fourth child really)
109 internal bool HasChild3 { get { return m_children.Count > 3; } }
111 #region equivalence functions
113 /// Is this subtree equivalent to another subtree
115 /// <param name="other"></param>
116 /// <returns></returns>
117 internal bool IsEquivalent(Node other)
119 if (this.Children.Count != other.Children.Count)
123 bool? opEquivalent = this.Op.IsEquivalent(other.Op);
124 if (opEquivalent != true)
128 for (int i = 0; i < this.Children.Count; i++)
130 if (!this.Children[i].IsEquivalent(other.Children[i]))
139 #region NodeInfo methods and properties
141 /// Has the node info been initialized, i.e. previously computed
143 internal bool IsNodeInfoInitialized { get { return (m_nodeInfo != null); } }
146 /// Get the nodeInfo for a node. Initializes it, if it has not yet been initialized
148 /// <param name="command">Current command object</param>
149 /// <returns>NodeInfo for this node</returns>
150 internal NodeInfo GetNodeInfo(Command command)
152 if (m_nodeInfo == null)
154 InitializeNodeInfo(command);
159 /// Gets the "extended" nodeinfo for a node; if it has not yet been initialized, then it will be
161 /// <param name="command">current command object</param>
162 /// <returns>extended nodeinfo for this node</returns>
163 internal ExtendedNodeInfo GetExtendedNodeInfo(Command command)
165 if (m_nodeInfo == null)
167 InitializeNodeInfo(command);
169 ExtendedNodeInfo extendedNodeInfo = m_nodeInfo as ExtendedNodeInfo;
170 Debug.Assert(extendedNodeInfo != null);
171 return extendedNodeInfo;
174 private void InitializeNodeInfo(Command command)
176 if (this.Op.IsRelOp || this.Op.IsPhysicalOp)
178 m_nodeInfo = new ExtendedNodeInfo(command);
182 m_nodeInfo = new NodeInfo(command);
184 command.RecomputeNodeInfo(this);