1 /* Copyright (C) 2014 InfiniDB, Inc.
2 
3    This program is free software; you can redistribute it and/or
4    modify it under the terms of the GNU General Public License
5    as published by the Free Software Foundation; version 2 of
6    the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16    MA 02110-1301, USA. */
17 
18 /***********************************************************************
19 *   $Id: arithmeticoperator.cpp 9210 2013-01-21 14:10:42Z rdempsey $
20 *
21 *
22 ***********************************************************************/
23 #include <iostream>
24 
25 #include "bytestream.h"
26 #include "arithmeticoperator.h"
27 #include "objectreader.h"
28 
29 using namespace std;
30 
31 namespace execplan
32 {
33 
34 /**
35  * Constructors/Destructors
36  */
ArithmeticOperator()37 ArithmeticOperator::ArithmeticOperator() : Operator()
38 {
39 }
40 
ArithmeticOperator(const string & operatorName)41 ArithmeticOperator::ArithmeticOperator(const string& operatorName): Operator(operatorName)
42 {
43 }
44 
ArithmeticOperator(const ArithmeticOperator & rhs)45 ArithmeticOperator::ArithmeticOperator(const ArithmeticOperator& rhs):
46     Operator(rhs),
47     fTimeZone(rhs.timeZone())
48 {
49 }
50 
~ArithmeticOperator()51 ArithmeticOperator:: ~ArithmeticOperator()
52 {
53 }
54 
55 /**
56  * Operations
57  */
58 
59 /**
60  * friend function
61  */
operator <<(ostream & output,const ArithmeticOperator & rhs)62 ostream& operator<<(ostream& output, const ArithmeticOperator& rhs)
63 {
64     output << rhs.toString();
65     output << "opType=" << rhs.operationType().colDataType << endl;
66     return output;
67 }
68 
69 /**
70  * The serialization interface
71  */
serialize(messageqcpp::ByteStream & b) const72 void ArithmeticOperator::serialize(messageqcpp::ByteStream& b) const
73 {
74     b << (ObjectReader::id_t) ObjectReader::ARITHMETICOPERATOR;
75     b << fTimeZone;
76     Operator::serialize(b);
77 }
78 
unserialize(messageqcpp::ByteStream & b)79 void ArithmeticOperator::unserialize(messageqcpp::ByteStream& b)
80 {
81     ObjectReader::checkType(b, ObjectReader::ARITHMETICOPERATOR);
82     b >> fTimeZone;
83     Operator::unserialize(b);
84 }
85 
operator ==(const ArithmeticOperator & t) const86 bool ArithmeticOperator::operator==(const ArithmeticOperator& t) const
87 {
88     if (data() != t.data())
89         return false;
90 
91     if (timeZone() != t.timeZone())
92         return false;
93 
94     return true;
95 }
96 
operator ==(const TreeNode * t) const97 bool ArithmeticOperator::operator==(const TreeNode* t) const
98 {
99     const ArithmeticOperator* o;
100 
101     o = dynamic_cast<const ArithmeticOperator*>(t);
102 
103     if (o == NULL)
104         return false;
105 
106     return *this == *o;
107 }
108 
operator !=(const ArithmeticOperator & t) const109 bool ArithmeticOperator::operator!=(const ArithmeticOperator& t) const
110 {
111     return (!(*this == t));
112 }
113 
operator !=(const TreeNode * t) const114 bool ArithmeticOperator::operator!=(const TreeNode* t) const
115 {
116     return (!(*this == t));
117 }
118 
119 #if 0
120 void ArithmeticOperator::operationType(const Type& l, const Type& r)
121 {
122     if (l.colDataType == execplan::CalpontSystemCatalog::DECIMAL)
123     {
124         switch (r.colDataType)
125         {
126             case execplan::CalpontSystemCatalog::DECIMAL:
127             {
128                 // should follow the result type that MySQL gives
129                 fOperationType = fResultType;
130                 break;
131             }
132 
133             case execplan::CalpontSystemCatalog::INT:
134             case execplan::CalpontSystemCatalog::MEDINT:
135             case execplan::CalpontSystemCatalog::TINYINT:
136             case execplan::CalpontSystemCatalog::BIGINT:
137                 fOperationType.colDataType = execplan::CalpontSystemCatalog::DECIMAL;
138                 fOperationType.scale = l.scale;
139                 break;
140 
141             default:
142                 fOperationType.colDataType = execplan::CalpontSystemCatalog::DOUBLE;
143         }
144     }
145     else if (r.colDataType == execplan::CalpontSystemCatalog::DECIMAL)
146     {
147         switch (l.colDataType)
148         {
149             case execplan::CalpontSystemCatalog::DECIMAL:
150             {
151                 // should following the result type that MySQL gives based on the following logic?
152                 // @NOTE is this trustable?
153                 fOperationType = fResultType;
154                 break;
155             }
156 
157             case execplan::CalpontSystemCatalog::INT:
158             case execplan::CalpontSystemCatalog::MEDINT:
159             case execplan::CalpontSystemCatalog::TINYINT:
160             case execplan::CalpontSystemCatalog::BIGINT:
161                 fOperationType.colDataType = execplan::CalpontSystemCatalog::DECIMAL;
162                 fOperationType.scale = r.scale;
163                 break;
164 
165             default:
166                 fOperationType.colDataType = execplan::CalpontSystemCatalog::DOUBLE;
167         }
168     }
169     else if ((l.colDataType == execplan::CalpontSystemCatalog::INT ||
170               l.colDataType == execplan::CalpontSystemCatalog::MEDINT ||
171               l.colDataType == execplan::CalpontSystemCatalog::TINYINT ||
172               l.colDataType == execplan::CalpontSystemCatalog::BIGINT) &&
173              (r.colDataType == execplan::CalpontSystemCatalog::INT ||
174               r.colDataType == execplan::CalpontSystemCatalog::MEDINT ||
175               r.colDataType == execplan::CalpontSystemCatalog::TINYINT ||
176               r.colDataType == execplan::CalpontSystemCatalog::BIGINT))
177         fOperationType.colDataType = execplan::CalpontSystemCatalog::BIGINT;
178     else
179         fOperationType.colDataType = execplan::CalpontSystemCatalog::DOUBLE;
180 }
181 #endif
182 
adjustResultType(const CalpontSystemCatalog::ColType & m)183 void ArithmeticOperator::adjustResultType(const CalpontSystemCatalog::ColType& m)
184 {
185     if (m.colDataType != CalpontSystemCatalog::DECIMAL)
186     {
187         fResultType = m;
188     }
189     else
190     {
191         CalpontSystemCatalog::ColType n;
192         n.colDataType = CalpontSystemCatalog::LONGDOUBLE;
193         n.scale = m.scale; // @bug5736, save the original decimal scale
194         n.precision = -1;  // @bug5736, indicate this double is for decimal math
195         n.colWidth = sizeof(long double);
196         fResultType = n;
197     }
198 }
199 
200 }  // namespace
201