Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Data / System / Data / Filter / UnaryNode.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="UnaryNode.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">[....]</owner>
6 // <owner current="true" primary="false">[....]</owner>
7 // <owner current="false" primary="false">[....]</owner>
8 //------------------------------------------------------------------------------
9
10 namespace System.Data {
11     using System;
12     using System.Collections.Generic;
13     using System.Diagnostics;
14     using System.Data.Common;
15     using System.Data.SqlTypes;
16
17
18     internal sealed class UnaryNode : ExpressionNode {
19         internal readonly int op;
20
21         internal ExpressionNode right;
22
23         internal UnaryNode(DataTable table, int op, ExpressionNode right) : base(table) {
24             this.op = op;
25             this.right = right;
26         }
27
28         internal override void Bind(DataTable table, List<DataColumn> list) {
29             BindTable(table);
30             right.Bind(table, list);
31         }
32
33         internal override object Eval() {
34             return Eval(null, DataRowVersion.Default);
35         }
36
37         internal override object Eval(DataRow row, DataRowVersion version) {
38             return EvalUnaryOp(op, right.Eval(row, version));
39         }
40
41         internal override object Eval(int[] recordNos) {
42             return right.Eval(recordNos);
43         }
44
45         private object EvalUnaryOp(int op, object vl) {
46             object value = DBNull.Value;
47
48             if (DataExpression.IsUnknown(vl))
49                 return DBNull.Value;
50
51             StorageType storageType;
52             switch (op) {
53                 case Operators.Noop:
54                     return vl;
55                 case Operators.UnaryPlus:
56                     storageType = DataStorage.GetStorageType(vl.GetType());
57                     if (ExpressionNode.IsNumericSql(storageType)) {
58                         return vl;
59                     }
60                     throw ExprException.TypeMismatch(this.ToString());
61
62                 case Operators.Negative:
63                     // the have to be better way for doing this..
64                     storageType = DataStorage.GetStorageType(vl.GetType());
65                     if (ExpressionNode.IsNumericSql(storageType)) {
66                         switch(storageType) {
67                         case StorageType.Byte:
68                             value = -(Byte) vl;
69                             break;
70                         case StorageType.Int16:
71                             value = -(Int16) vl;
72                             break;
73                         case StorageType.Int32:
74                             value = -(Int32) vl;
75                             break;
76                         case StorageType.Int64:
77                             value = -(Int64) vl;
78                             break;
79                         case StorageType.Single:
80                             value = -(Single) vl;
81                             break;
82                         case StorageType.Double:
83                             value = -(Double) vl;
84                             break;
85                         case StorageType.Decimal:
86                             value = -(Decimal) vl;
87                             break;
88                         case StorageType.SqlDecimal:
89                             value = -(SqlDecimal) vl;
90                             break;
91                         case StorageType.SqlDouble:
92                             value = -(SqlDouble) vl;
93                             break;
94                         case StorageType.SqlSingle:
95                             value = -(SqlSingle) vl;
96                             break;
97                         case StorageType.SqlMoney:
98                             value = -(SqlMoney) vl;
99                             break;
100                         case StorageType.SqlInt64:
101                             value = -(SqlInt64) vl;
102                             break;
103                         case StorageType.SqlInt32:
104                             value = -(SqlInt32) vl;
105                             break;
106                         case StorageType.SqlInt16:
107                             value = -(SqlInt16) vl;
108                             break;
109                         default:
110                             Debug.Assert(false, "Missing a type conversion");
111                             value = DBNull.Value;
112                             break;
113                         }
114                         return value;
115                     }
116
117                     throw ExprException.TypeMismatch(this.ToString());
118
119                 case Operators.Not:
120                     if (vl is SqlBoolean){
121                             if (((SqlBoolean)vl).IsFalse){
122                                 return SqlBoolean.True;
123                             }
124                             else if (((SqlBoolean)vl).IsTrue) {
125                                       return SqlBoolean.False;
126                             }
127                             throw ExprException.UnsupportedOperator(op);  // or should the result of not SQLNull  be SqlNull ?
128                     }
129                     else{
130                           if (DataExpression.ToBoolean(vl) != false)
131                              return false;
132                           return true;
133                     }
134
135                 default:
136                     throw ExprException.UnsupportedOperator(op);
137             }
138         }
139
140         internal override bool IsConstant() {
141             return(right.IsConstant());
142         }
143
144         internal override bool IsTableConstant() {
145             return(right.IsTableConstant());
146         }
147
148         internal override bool HasLocalAggregate() {
149             return(right.HasLocalAggregate());
150         }
151         
152         internal override bool HasRemoteAggregate() {
153             return(right.HasRemoteAggregate());
154         }
155
156         internal override bool DependsOn(DataColumn column) {
157             return(right.DependsOn(column));
158         }
159
160
161         internal override ExpressionNode Optimize() {
162             right = right.Optimize();
163
164             if (this.IsConstant()) {
165                 object val = this.Eval();
166
167                 return new ConstNode(table, ValueType.Object,  val, false);
168             }
169             else
170                 return this;
171         }
172     }
173 }