1 //------------------------------------------------------------------------------
2 // <copyright file="NameNode.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 // <owner current="false" primary="false">Microsoft</owner>
8 //------------------------------------------------------------------------------
10 namespace System.Data {
12 using System.ComponentModel;
13 using System.Collections.Generic;
14 using System.Diagnostics;
15 using System.Globalization;
17 internal sealed class NameNode : ExpressionNode {
18 internal char open = '\0';
19 internal char close = '\0';
22 internal bool type = false;
23 internal DataColumn column;
25 internal NameNode(DataTable table, char[] text, int start, int pos) : base(table) {
26 this.name = ParseName(text, start, pos);
29 internal NameNode(DataTable table, string name) : base(table) {
33 internal override bool IsSqlColumn{
35 return column.IsSqlType;
39 internal override void Bind(DataTable table, List<DataColumn> list) {
42 throw ExprException.UnboundName(name);
45 this.column = table.Columns[name];
50 if (!Common.ADP.IsCatchableExceptionType(e)) {
53 throw ExprException.UnboundName(name);
57 throw ExprException.UnboundName(name);
59 name = column.ColumnName;
62 // add column to the dependency list, do not add duplicate columns
63 Debug.Assert(column != null, "Failed to bind column " + name);
66 for (i = 0; i < list.Count; i++) {
67 // walk the list, check if the current column already on the list
68 DataColumn dataColumn = list[i];
69 if (column == dataColumn) {
73 if (i >= list.Count) {
78 internal override object Eval() {
79 // can not eval column without ROW value;
80 throw ExprException.EvalNoContext();
83 internal override object Eval(DataRow row, DataRowVersion version) {
85 throw ExprException.UnboundName(name);
89 if(IsTableConstant()) // this column is TableConstant Aggregate Function
90 return column.DataExpression.Evaluate();
92 throw ExprException.UnboundName(name);
96 return column[row.GetRecordFromVersion(version)];
99 internal override object Eval(int[] records) {
100 throw ExprException.ComputeNotAggregate(this.ToString());
103 internal override bool IsConstant() {
107 internal override bool IsTableConstant() {
108 if (column != null && column.Computed) {
109 return this.column.DataExpression.IsTableAggregate();
114 internal override bool HasLocalAggregate() {
115 if (column != null && column.Computed) {
116 return this.column.DataExpression.HasLocalAggregate();
121 internal override bool HasRemoteAggregate() {
122 if (column != null && column.Computed) {
123 return this.column.DataExpression.HasRemoteAggregate();
128 internal override bool DependsOn(DataColumn column) {
129 if (this.column == column)
132 if (this.column.Computed) {
133 return this.column.DataExpression.DependsOn(column);
139 internal override ExpressionNode Optimize() {
144 /// Parses given name and checks it validity
146 internal static string ParseName(char[] text, int start, int pos) {
148 string charsToEscape = "";
149 int saveStart = start;
152 if (text[start] == '`') {
153 Debug.Assert(text[checked((int)pos-1)] == '`', "Invalid identifyer bracketing, pos = " + pos.ToString(CultureInfo.InvariantCulture) + ", end = " + text[checked((int)pos-1)].ToString(CultureInfo.InvariantCulture));
154 start = checked((int)start+1);
155 pos = checked((int)pos-1);
159 else if (text[start] == '[') {
160 Debug.Assert(text[checked((int)pos-1)] == ']', "Invalid identifyer bracketing of name " + new string(text, start, pos-start) + " pos = " + pos.ToString(CultureInfo.InvariantCulture) + ", end = " + text[checked((int)pos-1)].ToString(CultureInfo.InvariantCulture));
161 start = checked((int)start+1);
162 pos = checked((int)pos-1);
164 charsToEscape = "]\\";
168 // scan the name in search for the ESC
171 for (int i = start; i < pos; i++) {
172 if (text[i] == esc) {
173 if (i+1 < pos && charsToEscape.IndexOf(text[i+1]) >= 0) {
177 text[posEcho] = text[i];
184 throw ExprException.InvalidName(new string(text, saveStart, savePos - saveStart));
186 return new string(text, start, pos - start);