1 //------------------------------------------------------------------------------
2 // <copyright file="UnaryNode.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">[....]</owner>
6 // <owner current="true" primary="false">[....]</owner>
7 // <owner current="false" primary="false">[....]</owner>
8 //------------------------------------------------------------------------------
10 namespace System.Data {
12 using System.Collections.Generic;
13 using System.Diagnostics;
14 using System.Data.Common;
15 using System.Data.SqlTypes;
18 internal sealed class UnaryNode : ExpressionNode {
19 internal readonly int op;
21 internal ExpressionNode right;
23 internal UnaryNode(DataTable table, int op, ExpressionNode right) : base(table) {
28 internal override void Bind(DataTable table, List<DataColumn> list) {
30 right.Bind(table, list);
33 internal override object Eval() {
34 return Eval(null, DataRowVersion.Default);
37 internal override object Eval(DataRow row, DataRowVersion version) {
38 return EvalUnaryOp(op, right.Eval(row, version));
41 internal override object Eval(int[] recordNos) {
42 return right.Eval(recordNos);
45 private object EvalUnaryOp(int op, object vl) {
46 object value = DBNull.Value;
48 if (DataExpression.IsUnknown(vl))
51 StorageType storageType;
55 case Operators.UnaryPlus:
56 storageType = DataStorage.GetStorageType(vl.GetType());
57 if (ExpressionNode.IsNumericSql(storageType)) {
60 throw ExprException.TypeMismatch(this.ToString());
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)) {
67 case StorageType.Byte:
70 case StorageType.Int16:
73 case StorageType.Int32:
76 case StorageType.Int64:
79 case StorageType.Single:
82 case StorageType.Double:
85 case StorageType.Decimal:
86 value = -(Decimal) vl;
88 case StorageType.SqlDecimal:
89 value = -(SqlDecimal) vl;
91 case StorageType.SqlDouble:
92 value = -(SqlDouble) vl;
94 case StorageType.SqlSingle:
95 value = -(SqlSingle) vl;
97 case StorageType.SqlMoney:
98 value = -(SqlMoney) vl;
100 case StorageType.SqlInt64:
101 value = -(SqlInt64) vl;
103 case StorageType.SqlInt32:
104 value = -(SqlInt32) vl;
106 case StorageType.SqlInt16:
107 value = -(SqlInt16) vl;
110 Debug.Assert(false, "Missing a type conversion");
111 value = DBNull.Value;
117 throw ExprException.TypeMismatch(this.ToString());
120 if (vl is SqlBoolean){
121 if (((SqlBoolean)vl).IsFalse){
122 return SqlBoolean.True;
124 else if (((SqlBoolean)vl).IsTrue) {
125 return SqlBoolean.False;
127 throw ExprException.UnsupportedOperator(op); // or should the result of not SQLNull be SqlNull ?
130 if (DataExpression.ToBoolean(vl) != false)
136 throw ExprException.UnsupportedOperator(op);
140 internal override bool IsConstant() {
141 return(right.IsConstant());
144 internal override bool IsTableConstant() {
145 return(right.IsTableConstant());
148 internal override bool HasLocalAggregate() {
149 return(right.HasLocalAggregate());
152 internal override bool HasRemoteAggregate() {
153 return(right.HasRemoteAggregate());
156 internal override bool DependsOn(DataColumn column) {
157 return(right.DependsOn(column));
161 internal override ExpressionNode Optimize() {
162 right = right.Optimize();
164 if (this.IsConstant()) {
165 object val = this.Eval();
167 return new ConstNode(table, ValueType.Object, val, false);