1 /* Copyright (C) 2014 InfiniDB, Inc.
2 Copyright (C) 2019 MariaDB Corporation
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; version 2 of
7 the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 MA 02110-1301, USA. */
18
19 /***********************************************************************
20 * $Id: constantcolumn.cpp 9474 2013-05-02 15:28:09Z rdempsey $
21 *
22 *
23 ***********************************************************************/
24 #include <string>
25 #include <iostream>
26 #include <sstream>
27 using namespace std;
28
29 #include "bytestream.h"
30 #include "constantcolumn.h"
31 #include "objectreader.h"
32 using namespace messageqcpp;
33
34 #include "dataconvert.h"
35 #include "calpontsystemcatalog.h"
36
37 namespace execplan
38 {
39 /**
40 * Constructors/Destructors
41 */
ConstantColumn()42 ConstantColumn::ConstantColumn() :
43 ReturnedColumn(),
44 fType(0)
45 {
46 }
47
ConstantColumn(const string & sql,TYPE type)48 ConstantColumn::ConstantColumn(const string& sql, TYPE type) :
49 ReturnedColumn(),
50 fConstval(sql),
51 fType(type),
52 fData(sql)
53 {
54 fResult.strVal = sql;
55
56 if (type == LITERAL && sql.length() < 9)
57 {
58 memcpy(tmp, sql.c_str(), sql.length());
59 memset(tmp + sql.length(), 0, 8);
60 fResult.uintVal = uint64ToStr(*((uint64_t*) tmp));
61 fResult.intVal = (int64_t)fResult.uintVal;
62 }
63 else
64 {
65 fResult.intVal = atoll(sql.c_str());
66 fResult.uintVal = strtoull(sql.c_str(), NULL, 0);
67 }
68
69 fResult.floatVal = atof(sql.c_str());
70 fResult.doubleVal = atof(sql.c_str());
71 fResult.longDoubleVal = strtold(sql.c_str(), NULL);
72
73 // decimal for constant should be constructed by the caller and call the decimal constructor
74 fResult.decimalVal.value = fResult.intVal;
75 fResult.decimalVal.scale = 0;
76 fResult.decimalVal.precision = 18;
77
78 // @bug 3381, default null item to integer type.
79 if (fType == ConstantColumn::NULLDATA)
80 {
81 if (fResult.uintVal > (uint64_t)MAX_BIGINT)
82 {
83 fResultType.colDataType = CalpontSystemCatalog::UBIGINT;
84 }
85 else
86 {
87 fResultType.colDataType = CalpontSystemCatalog::BIGINT;
88 }
89
90 fResultType.colWidth = 8;
91 }
92 else
93 {
94 fResultType.colDataType = CalpontSystemCatalog::VARCHAR;
95 fResultType.colWidth = sql.length();
96 }
97 }
98
ConstantColumn(const string & sql,const double val)99 ConstantColumn::ConstantColumn(const string& sql, const double val) :
100 ReturnedColumn(),
101 fConstval(sql),
102 fType(NUM),
103 fData(sql)
104 {
105 fResult.strVal = sql;
106 fResult.doubleVal = val;
107 fResult.intVal = (int64_t)val;
108 fResult.uintVal = (uint64_t)val;
109 fResult.floatVal = (float)val;
110 fResult.longDoubleVal = val;
111 // decimal for constant should be constructed by the caller and call the decimal constructor
112 fResult.decimalVal.value = fResult.intVal;
113 fResult.decimalVal.scale = 0;
114 fResult.decimalVal.precision = 18;
115 fResultType.colDataType = CalpontSystemCatalog::DOUBLE;
116 fResultType.colWidth = 8;
117 }
118
ConstantColumn(const string & sql,const long double val)119 ConstantColumn::ConstantColumn(const string& sql, const long double val) :
120 ReturnedColumn(),
121 fConstval(sql),
122 fType(NUM),
123 fData(sql)
124 {
125 fResult.strVal = sql;
126 fResult.doubleVal = (double)val;
127 fResult.intVal = (int64_t)val;
128 fResult.uintVal = (uint64_t)val;
129 fResult.floatVal = (float)val;
130 fResult.longDoubleVal = val;
131 // decimal for constant should be constructed by the caller and call the decimal constructor
132 fResult.decimalVal.value = fResult.intVal;
133 fResult.decimalVal.scale = 0;
134 fResult.decimalVal.precision = 18;
135 fResultType.colDataType = CalpontSystemCatalog::DOUBLE;
136 fResultType.colWidth = 8;
137 }
138
ConstantColumn(const string & sql,const int64_t val,TYPE type)139 ConstantColumn::ConstantColumn(const string& sql, const int64_t val, TYPE type) :
140 ReturnedColumn(),
141 fConstval(sql),
142 fType(type),
143 fData(sql)
144 {
145 fResult.strVal = sql;
146 fResult.intVal = val;
147 fResult.uintVal = (uint64_t)fResult.intVal;
148 fResult.floatVal = (float)fResult.intVal;
149 fResult.doubleVal = (double)fResult.intVal;
150 fResult.longDoubleVal = (long double)fResult.intVal;
151 fResult.decimalVal.value = fResult.intVal;
152 fResult.decimalVal.scale = 0;
153 fResultType.colDataType = CalpontSystemCatalog::BIGINT;
154 fResultType.colWidth = 8;
155 }
156
ConstantColumn(const string & sql,const uint64_t val,TYPE type)157 ConstantColumn::ConstantColumn(const string& sql, const uint64_t val, TYPE type) :
158 ReturnedColumn(),
159 fConstval(sql),
160 fType(type),
161 fData(sql)
162 {
163 fResult.strVal = sql;
164 fResult.uintVal = val;
165 fResult.intVal = (int64_t)fResult.uintVal;
166 fResult.floatVal = (float)fResult.uintVal;
167 fResult.doubleVal = (double)fResult.uintVal;
168 fResult.longDoubleVal = (long double)fResult.uintVal;
169 fResult.decimalVal.value = fResult.uintVal;
170 fResult.decimalVal.scale = 0;
171 fResultType.colDataType = CalpontSystemCatalog::UBIGINT;
172 fResultType.colWidth = 8;
173 }
174
ConstantColumn(const string & sql,const IDB_Decimal & val)175 ConstantColumn::ConstantColumn(const string& sql, const IDB_Decimal& val) :
176 ReturnedColumn(),
177 fConstval(sql),
178 fType(NUM),
179 fData(sql)
180 {
181 fResult.strVal = sql;
182 fResult.intVal = (int64_t)atoll(sql.c_str());
183 fResult.uintVal = strtoull(sql.c_str(), NULL, 0);
184 fResult.floatVal = atof(sql.c_str());
185 fResult.doubleVal = atof(sql.c_str());
186 fResult.longDoubleVal = strtold(sql.c_str(), NULL);
187 fResult.decimalVal = val;
188 fResultType.colDataType = CalpontSystemCatalog::DECIMAL;
189 fResultType.colWidth = 8;
190 fResultType.scale = val.scale;
191 fResultType.precision = val.precision;
192 }
193
ConstantColumn(const ConstantColumn & rhs)194 ConstantColumn::ConstantColumn( const ConstantColumn& rhs):
195 ReturnedColumn(rhs),
196 fConstval (rhs.constval()),
197 fType (rhs.type()),
198 fData (rhs.data()),
199 fTimeZone (rhs.timeZone())
200 {
201 sequence(rhs.sequence());
202 fAlias = rhs.alias();
203 fResult = rhs.fResult;
204 fResultType = rhs.fResultType;
205 }
206
ConstantColumn(const int64_t val,TYPE type)207 ConstantColumn::ConstantColumn(const int64_t val, TYPE type) :
208 ReturnedColumn(),
209 fType(type)
210 {
211 ostringstream oss;
212 oss << val;
213 fConstval = oss.str();
214 fData = oss.str();
215 fResult.strVal = fData;
216 fResult.intVal = val;
217 fResult.uintVal = (uint64_t)fResult.intVal;
218 fResult.floatVal = (float)fResult.intVal;
219 fResult.doubleVal = (double)fResult.intVal;
220 fResult.longDoubleVal = (long double)fResult.intVal;
221 fResult.decimalVal.value = fResult.intVal;
222 fResult.decimalVal.scale = 0;
223 fResultType.colDataType = CalpontSystemCatalog::BIGINT;
224 fResultType.colWidth = 8;
225 }
226
ConstantColumn(const uint64_t val,TYPE type)227 ConstantColumn::ConstantColumn(const uint64_t val, TYPE type) :
228 ReturnedColumn(),
229 fType(type)
230 {
231 ostringstream oss;
232 oss << val;
233 fConstval = oss.str();
234 fData = oss.str();
235 fResult.strVal = fData;
236 fResult.intVal = (int64_t)val;
237 fResult.uintVal = val;
238 fResult.floatVal = (float)fResult.uintVal;
239 fResult.doubleVal = (double)fResult.uintVal;
240 fResult.longDoubleVal = (long double)fResult.uintVal;
241 fResult.decimalVal.value = fResult.uintVal;
242 fResult.decimalVal.scale = 0;
243 fResultType.colDataType = CalpontSystemCatalog::UBIGINT;
244 fResultType.colWidth = 8;
245 }
246
~ConstantColumn()247 ConstantColumn::~ConstantColumn()
248 {
249 }
250
toString() const251 const string ConstantColumn::toString() const
252 {
253 ostringstream oss;
254 oss << "ConstantColumn: " << fConstval << " intVal=" << fResult.intVal << " uintVal=" << fResult.uintVal;
255 oss << '(';
256
257 if (fType == LITERAL)
258 oss << 'l';
259 else if (fType == NUM)
260 oss << 'n';
261 else
262 oss << "null";
263
264 oss << ')';
265 oss << " resultType=" << colDataTypeToString(fResultType.colDataType);
266
267 if (fAlias.length() > 0) oss << "/Alias: " << fAlias;
268
269 return oss.str();
270 }
271
data() const272 const string ConstantColumn::data() const
273 {
274 return fData;
275 }
276
operator <<(ostream & output,const ConstantColumn & rhs)277 ostream& operator<<(ostream& output, const ConstantColumn& rhs)
278 {
279 output << rhs.toString();
280
281 return output;
282 }
283
serialize(messageqcpp::ByteStream & b) const284 void ConstantColumn::serialize(messageqcpp::ByteStream& b) const
285 {
286
287 b << (ObjectReader::id_t) ObjectReader::CONSTANTCOLUMN;
288 ReturnedColumn::serialize(b);
289 b << fConstval;
290 b << (uint32_t) fType;
291 //b << fAlias;
292 b << fData;
293 b << fTimeZone;
294 b << static_cast<ByteStream::doublebyte>(fReturnAll);
295 b << (uint64_t)fResult.intVal;
296 b << fResult.uintVal;
297 b << fResult.doubleVal;
298 b << fResult.longDoubleVal;
299 b << fResult.floatVal;
300 b << (uint8_t)fResult.boolVal;
301 b << fResult.strVal;
302 b << (uint64_t)fResult.decimalVal.value;
303 b << (uint8_t)fResult.decimalVal.scale;
304 b << (uint8_t)fResult.decimalVal.precision;
305 }
306
unserialize(messageqcpp::ByteStream & b)307 void ConstantColumn::unserialize(messageqcpp::ByteStream& b)
308 {
309
310 ObjectReader::checkType(b, ObjectReader::CONSTANTCOLUMN);
311 ReturnedColumn::unserialize(b);
312 //uint64_t val;
313
314 b >> fConstval;
315 b >> (uint32_t&) fType;
316 b >> fData;
317 b >> fTimeZone;
318 b >> reinterpret_cast< ByteStream::doublebyte&>(fReturnAll);
319 b >> (uint64_t&)fResult.intVal;
320 b >> fResult.uintVal;
321 b >> fResult.doubleVal;
322 b >> fResult.longDoubleVal;
323 b >> fResult.floatVal;
324 b >> (uint8_t&)fResult.boolVal;
325 b >> fResult.strVal;
326 b >> (uint64_t&)fResult.decimalVal.value;
327 b >> (uint8_t&)fResult.decimalVal.scale;
328 b >> (uint8_t&)fResult.decimalVal.precision;
329 }
330
operator ==(const ConstantColumn & t) const331 bool ConstantColumn::operator==(const ConstantColumn& t) const
332 {
333 const ReturnedColumn* rc1, *rc2;
334
335 rc1 = static_cast<const ReturnedColumn*>(this);
336 rc2 = static_cast<const ReturnedColumn*>(&t);
337
338 if (*rc1 != *rc2)
339 return false;
340
341 if (fConstval != t.fConstval)
342 return false;
343
344 if (fType != t.fType)
345 return false;
346
347
348 if (fData != t.fData)
349 return false;
350
351 if (fReturnAll != t.fReturnAll)
352 return false;
353
354 if (fTimeZone != t.fTimeZone)
355 return false;
356
357 return true;
358 }
359
operator ==(const TreeNode * t) const360 bool ConstantColumn::operator==(const TreeNode* t) const
361 {
362 const ConstantColumn* o;
363
364 o = dynamic_cast<const ConstantColumn*>(t);
365
366 if (o == NULL)
367 return false;
368
369 return *this == *o;
370 }
371
operator !=(const ConstantColumn & t) const372 bool ConstantColumn::operator!=(const ConstantColumn& t) const
373 {
374 return (!(*this == t));
375 }
376
operator !=(const TreeNode * t) const377 bool ConstantColumn::operator!=(const TreeNode* t) const
378 {
379 return (!(*this == t));
380 }
381
382 }
383 // vim:ts=4 sw=4:
384