Welcome to mirror list, hosted at ThFree Co, Russian Federation.

LookupNode.cs « Filter « Data « System « System.Data « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3b75a801cef46f53a8ec004d905a5ad910a3feb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//------------------------------------------------------------------------------
// <copyright file="LookupNode.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
// <owner current="true" primary="false">[....]</owner>
// <owner current="false" primary="false">[....]</owner>
//------------------------------------------------------------------------------

namespace System.Data {
    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Diagnostics;

    internal sealed class LookupNode : ExpressionNode {
        private readonly string relationName;    // can be null
        private readonly string columnName;

        private DataColumn column;
        private DataRelation relation;

        internal LookupNode(DataTable table, string columnName, string relationName) : base(table) {
            this.relationName = relationName;
            this.columnName = columnName;
        }

        internal override void Bind(DataTable table, List<DataColumn> list) {
            BindTable(table);
            column = null;  // clear for rebinding (if original binding was valid)
            relation = null;

            if (table == null)
                throw ExprException.ExpressionUnbound(this.ToString());

            // First find parent table

            DataRelationCollection relations;
            relations = table.ParentRelations;

            if (relationName == null) {
                // must have one and only one relation

                if (relations.Count > 1) {
                    throw ExprException.UnresolvedRelation(table.TableName, this.ToString());
                }
                relation = relations[0];
            }
            else {
                relation = relations[relationName];
            }
            if (null == relation) {
                throw ExprException.BindFailure(relationName);// WebData 112162: this operation is not clne specific, throw generic exception
            }
            DataTable parentTable = relation.ParentTable;

            Debug.Assert(relation != null, "Invalid relation: no parent table.");
            Debug.Assert(columnName != null, "All Lookup expressions have columnName set.");

            this.column = parentTable.Columns[columnName];

            if (column == null)
                throw ExprException.UnboundName(columnName);

            // add column to the dependency list

            int i;
            for (i = 0; i < list.Count; i++) {
                // walk the list, check if the current column already on the list
                DataColumn dataColumn = list[i];
                if (column == dataColumn) {
                    break;
                }
            }
            if (i >= list.Count) {
                list.Add(column);
            }

            // SQLBU 383715: Staleness of computed values in expression column as the relationship end columns are not being added to the dependent column list.
            AggregateNode.Bind(relation, list);
        }

        internal override object Eval() {
            throw ExprException.EvalNoContext();
        }

        internal override object Eval(DataRow row, DataRowVersion version) {
            if (column == null || relation == null)
                throw ExprException.ExpressionUnbound(this.ToString());

            DataRow parent = row.GetParentRow(relation, version);
            if (parent == null)
                return DBNull.Value;

            return parent[column, parent.HasVersion(version) ? version : DataRowVersion.Current]; // [....] : Bug 76154
        }

        internal override object Eval(int[] recordNos) {
            throw ExprException.ComputeNotAggregate(this.ToString());
        }

        internal override bool IsConstant() {
            return false;
        }

        internal override bool IsTableConstant() {
            return false;
        }

        internal override bool HasLocalAggregate() {
            return false;
        }

        internal override bool HasRemoteAggregate() {
            return false;
        }

        internal override bool DependsOn(DataColumn column) {
            if (this.column == column) {
                return true;
            }
            return false;
        }

        internal override ExpressionNode Optimize() {
            return this;
        }
    }
}