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