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: operator.cpp 9210 2013-01-21 14:10:42Z rdempsey $
20 *
21 *
22 ***********************************************************************/
23 #include <iostream>
24 #include <sstream>
25
26 #include "bytestream.h"
27 #include "operator.h"
28 #include "objectreader.h"
29
30 using namespace std;
31
32 namespace
33 {
34
35 /**@brief util struct for converting string to lower case */
36 struct to_lower
37 {
operator ()__anon7b3d7e270111::to_lower38 char operator() (char c) const
39 {
40 return tolower(c);
41 }
42 };
43
44 //Trim any leading/trailing ws
lrtrim(const string & in)45 const string lrtrim(const string& in)
46 {
47 string::size_type p1;
48 p1 = in.find_first_not_of(" \t\n");
49
50 if (p1 == string::npos) p1 = 0;
51
52 string::size_type p2;
53 p2 = in.find_last_not_of(" \t\n");
54
55 if (p2 == string::npos) p2 = in.size() - 1;
56
57 return string(in, p1, (p2 - p1 + 1));
58 }
59
60 }
61
62 namespace execplan
63 {
64
65 /**
66 * Constructors/Destructors
67 */
Operator()68 Operator::Operator()
69 {
70 }
71
Operator(const string & operatorName)72 Operator::Operator(const string& operatorName)
73 {
74 data(operatorName);
75 }
76
Operator(const Operator & rhs)77 Operator::Operator(const Operator& rhs) :
78 TreeNode(rhs),
79 fOp(rhs.op())
80 {
81 data(rhs.fData);
82 }
83
~Operator()84 Operator:: ~Operator()
85 {
86 }
87
88 /**
89 * Operations
90 */
data(const string data)91 void Operator::data(const string data)
92 {
93 fData = lrtrim(data);
94 transform (fData.begin(), fData.end(), fData.begin(), to_lower());
95
96 if (fData == "+")
97 {
98 fOp = OP_ADD;
99 }
100 else if (fData == "-")
101 {
102 fOp = OP_SUB;
103 }
104 else if (fData == "*")
105 {
106 fOp = OP_MUL;
107 }
108 else if (fData == "/")
109 {
110 fOp = OP_DIV;
111 }
112 else if (fData == "=")
113 {
114 fOp = OP_EQ;
115 }
116 else if (fData == "!=" || fData == "<>")
117 {
118 fOp = OP_NE;
119 }
120 else if (fData == ">")
121 {
122 fOp = OP_GT;
123 }
124 else if (fData == ">=")
125 {
126 fOp = OP_GE;
127 }
128 else if (fData == "<")
129 {
130 fOp = OP_LT;
131 }
132 else if (fData == "<=")
133 {
134 fOp = OP_LE;
135 }
136 else if (fData == "and")
137 {
138 fOp = OP_AND;
139 }
140 else if (fData == "or")
141 {
142 fOp = OP_OR;
143 }
144 else if (fData == "like")
145 {
146 fOp = OP_LIKE;
147 }
148 else if (fData == "not like")
149 {
150 fOp = OP_NOTLIKE;
151 fData = "not like";
152 }
153 else if (fData == "isnull")
154 {
155 fOp = OP_ISNULL;
156 fData = "is null";
157 }
158 else if (fData == "isnotnull")
159 {
160 fOp = OP_ISNOTNULL;
161 fData = "is not null";
162 }
163 else if (fData == "xor")
164 {
165 fOp = OP_XOR;
166 }
167 else
168 {
169 fOp = OP_UNKNOWN;
170 }
171 }
172
toString() const173 const string Operator::toString() const
174 {
175 ostringstream oss;
176 oss << string("Operator: " + fData) << " fOp=" << fOp;
177 oss << " " << "opType=" << fOperationType.colDataType;
178 return oss.str();
179 }
180
opposite() const181 Operator* Operator::opposite() const
182 {
183 if (fData.compare(">") == 0)
184 return new Operator("<");
185
186 if (fData.compare("<") == 0)
187 return new Operator(">");
188
189 if (fData.compare(">=") == 0)
190 return new Operator("<=");
191
192 if (fData.compare("<=") == 0)
193 return new Operator(">=");
194
195 return this->clone();
196 }
197
198 /**
199 * friend function
200 */
operator <<(ostream & output,const Operator & rhs)201 ostream& operator<<(ostream& output, const Operator& rhs)
202 {
203 output << rhs.toString();
204 return output;
205 }
206
207 /**
208 * The serialization interface
209 */
serialize(messageqcpp::ByteStream & b) const210 void Operator::serialize(messageqcpp::ByteStream& b) const
211 {
212 b << (ObjectReader::id_t) ObjectReader::OPERATOR;
213 b << fData;
214 fResultType.serialize(b);
215 fOperationType.serialize(b);
216 b << (uint32_t)fOp;
217 }
218
unserialize(messageqcpp::ByteStream & b)219 void Operator::unserialize(messageqcpp::ByteStream& b)
220 {
221 uint32_t val;
222 ObjectReader::checkType(b, ObjectReader::OPERATOR);
223 b >> fData;
224 fResultType.unserialize(b);
225 fOperationType.unserialize(b);
226
227 b >> (uint32_t&)val;
228 fOp = (OpType)val;
229
230 fResult.decimalVal.scale = fResultType.scale;
231 fResult.decimalVal.precision = fResultType.precision;
232 }
233
operator ==(const Operator & t) const234 bool Operator::operator==(const Operator& t) const
235 {
236 if (fOp == t.fOp)
237 return true;
238
239 return false;
240 }
241
operator ==(const TreeNode * t) const242 bool Operator::operator==(const TreeNode* t) const
243 {
244 const Operator* o;
245
246 o = dynamic_cast<const Operator*>(t);
247
248 if (o == NULL)
249 return false;
250
251 return *this == *o;
252 }
253
operator !=(const Operator & t) const254 bool Operator::operator!=(const Operator& t) const
255 {
256 return (!(*this == t));
257 }
258
operator !=(const TreeNode * t) const259 bool Operator::operator!=(const TreeNode* t) const
260 {
261 return (!(*this == t));
262 }
263
reverseOp()264 void Operator::reverseOp()
265 {
266 switch (fOp)
267 {
268 case OP_EQ:
269 fOp = OP_NE;
270 fData = "!=";
271 break;
272
273 case OP_NE:
274 fOp = OP_EQ;
275 fData = "=";
276 break;
277
278 case OP_GT:
279 fOp = OP_LT;
280 fData = "<";
281 break;
282
283 case OP_GE:
284 fOp = OP_LE;
285 fData = "<=";
286 break;
287
288 case OP_LT:
289 fOp = OP_GT;
290 fData = ">";
291 break;
292
293 case OP_LE:
294 fOp = OP_GE;
295 fData = ">=";
296 break;
297
298 case OP_LIKE:
299 fOp = OP_NOTLIKE;
300 fData = "not like";
301 break;
302
303 case OP_NOTLIKE:
304 fOp = OP_LIKE;
305 fData = "like";
306 break;
307
308 case OP_ISNULL:
309 fOp = OP_ISNOTNULL;
310 fData = "isnotnull";
311 break;
312
313 case OP_ISNOTNULL:
314 fOp = OP_ISNULL;
315 fData = "isnull";
316 break;
317
318 case OP_BETWEEN:
319 fOp = OP_NOTBETWEEN;
320 fData = "not between";
321 break;
322
323 case OP_NOTBETWEEN:
324 fOp = OP_BETWEEN;
325 fData = "between";
326 break;
327
328 case OP_IN:
329 fOp = OP_NOTIN;
330 fData = "not in";
331 break;
332
333 case OP_NOTIN:
334 fOp = OP_IN;
335 fData = "in";
336 break;
337
338 default:
339 fOp = OP_UNKNOWN;
340 fData = "unknown";
341 break;
342 }
343 }
344
345 } // namespace
346