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$
20 *
21 *******************************************************************************/
22 
23 
24 #ifndef WE_DDLCOMMON_H
25 #define WE_DDLCOMMON_H
26 
27 #include <string>
28 #include <stdexcept>
29 #include <sstream>
30 #include <iostream>
31 #include <stdint.h>
32 
33 #include <boost/any.hpp>
34 #include <boost/tuple/tuple.hpp>
35 
36 #include "calpontsystemcatalog.h"
37 #include "objectidmanager.h"
38 #include "sessionmanager.h"
39 #include "ddlpkg.h"
40 #include "messageobj.h"
41 #include "we_type.h"
42 #include "we_define.h"
43 #include "writeengine.h"
44 #include "columnresult.h"
45 #include "brmtypes.h"
46 #include "joblist.h"
47 
48 #if defined(_MSC_VER) && defined(xxxDDLPKGPROC_DLLEXPORT)
49 #define EXPORT __declspec(dllexport)
50 #else
51 #define EXPORT
52 #endif
53 
54 #include <boost/algorithm/string/case_conv.hpp>
55 
56 template <class T>
from_string(T & t,const std::string & s,std::ios_base & (* f)(std::ios_base &))57 bool from_string(T& t,
58                  const std::string& s,
59                  std::ios_base & (*f)(std::ios_base&))
60 {
61     std::istringstream iss(s);
62     return !(iss >> f >> t).fail();
63 }
64 
65 namespace WriteEngine
66 {
67 struct DDLColumn
68 {
69     execplan::CalpontSystemCatalog::OID oid;
70     execplan::CalpontSystemCatalog::ColType colType;
71     execplan::CalpontSystemCatalog::TableColName tableColName;
72 };
73 
74 typedef std::vector<DDLColumn> ColumnList;
75 
76 struct DictOID
77 {
78     int dictOID;
79     int listOID;
80     int treeOID;
81     int colWidth;
82     int compressionType;
83 };
84 
85 struct extentInfo
86 {
87     uint16_t dbRoot;
88     uint32_t partition;
89     uint16_t segment;
90     bool operator==(const extentInfo& rhs) const
91     {
92         return (dbRoot == rhs.dbRoot && partition == rhs.partition && segment == rhs.segment);
93     }
94     bool operator!=(const extentInfo& rhs) const
95     {
96         return !(*this == rhs);
97     }
98 };
getColumnsForTable(uint32_t sessionID,std::string schema,std::string table,ColumnList & colList)99 inline void  getColumnsForTable(uint32_t sessionID, std::string schema, std::string table,
100                                 ColumnList& colList)
101 {
102 
103   execplan::CalpontSystemCatalog::TableName tableName;
104     tableName.schema = schema;
105     tableName.table = table;
106     std::string err;
107 
108     try
109     {
110         boost::shared_ptr<execplan::CalpontSystemCatalog> systemCatalogPtr = execplan::CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID);
111         systemCatalogPtr->identity(execplan::CalpontSystemCatalog::EC);
112 
113         const execplan::CalpontSystemCatalog::RIDList ridList = systemCatalogPtr->columnRIDs(tableName);
114 
115         execplan::CalpontSystemCatalog::RIDList::const_iterator rid_iterator = ridList.begin();
116 
117         while (rid_iterator != ridList.end())
118         {
119           execplan::CalpontSystemCatalog::ROPair roPair = *rid_iterator;
120 
121             DDLColumn column;
122             column.oid = roPair.objnum;
123             column.colType = systemCatalogPtr->colType(column.oid);
124             column.tableColName = systemCatalogPtr->colName(column.oid);
125 
126             colList.push_back(column);
127 
128             ++rid_iterator;
129         }
130 
131     }
132     catch (exception& ex)
133     {
134 
135         err = "DDLPackageProcessor::getColumnsForTable: while reading columns for table " +  schema + '.' + table + ": " + ex.what();
136         throw std::runtime_error(err);
137     }
138     catch (...)
139     {
140         err = "DDLPackageProcessor::getColumnsForTable: caught unkown exception!" ;
141         throw std::runtime_error(err);
142     }
143 
144 }
145 
getNullValueForType(const execplan::CalpontSystemCatalog::ColType & colType)146 inline boost::any getNullValueForType(const execplan::CalpontSystemCatalog::ColType& colType)
147 {
148     boost::any value;
149 
150     switch (colType.colDataType)
151     {
152         case execplan::CalpontSystemCatalog::BIT:
153             break;
154 
155         case execplan::CalpontSystemCatalog::TINYINT:
156         {
157             char tinyintvalue = joblist::TINYINTNULL;
158             value = tinyintvalue;
159 
160         }
161         break;
162 
163         case execplan::CalpontSystemCatalog::UTINYINT:
164         {
165             uint8_t tinyintvalue = joblist::UTINYINTNULL;
166             value = tinyintvalue;
167 
168         }
169         break;
170 
171         case execplan::CalpontSystemCatalog::SMALLINT:
172         {
173             short smallintvalue = joblist::SMALLINTNULL;
174             value = smallintvalue;
175         }
176         break;
177 
178         case execplan::CalpontSystemCatalog::USMALLINT:
179         {
180             uint16_t smallintvalue = joblist::USMALLINTNULL;
181             value = smallintvalue;
182         }
183         break;
184 
185         case execplan::CalpontSystemCatalog::MEDINT:
186         case execplan::CalpontSystemCatalog::INT:
187         {
188             int intvalue = joblist::INTNULL;
189             value = intvalue;
190         }
191         break;
192 
193         case execplan::CalpontSystemCatalog::UMEDINT:
194         case execplan::CalpontSystemCatalog::UINT:
195         {
196             uint32_t intvalue = joblist::UINTNULL;
197             value = intvalue;
198         }
199         break;
200 
201         case execplan::CalpontSystemCatalog::BIGINT:
202         {
203             long long bigint = joblist::BIGINTNULL;
204             value = bigint;
205         }
206         break;
207 
208         case execplan::CalpontSystemCatalog::UBIGINT:
209         {
210             uint64_t bigint = joblist::UBIGINTNULL;
211             value = bigint;
212         }
213         break;
214 
215         case execplan::CalpontSystemCatalog::DECIMAL:
216         case execplan::CalpontSystemCatalog::UDECIMAL:
217         {
218             if (colType.colWidth <= execplan::CalpontSystemCatalog::FOUR_BYTE)
219             {
220                 short smallintvalue = joblist::SMALLINTNULL;
221                 value = smallintvalue;
222             }
223             else if (colType.colWidth <= 9)
224             {
225                 int intvalue = joblist::INTNULL;
226                 value = intvalue;
227             }
228             else if (colType.colWidth <= 18)
229             {
230                 long long eightbyte = joblist::BIGINTNULL;
231                 value = eightbyte;
232             }
233             else
234             {
235                 WriteEngine::Token nullToken;
236                 value = nullToken;
237             }
238         }
239         break;
240 
241         case execplan::CalpontSystemCatalog::FLOAT:
242         case execplan::CalpontSystemCatalog::UFLOAT:
243         {
244             uint32_t jlfloatnull = joblist::FLOATNULL;
245             float* fp = reinterpret_cast<float*>(&jlfloatnull);
246             value = *fp;
247         }
248         break;
249 
250         case execplan::CalpontSystemCatalog::DOUBLE:
251         case execplan::CalpontSystemCatalog::UDOUBLE:
252         {
253             uint64_t jldoublenull = joblist::DOUBLENULL;
254             double* dp = reinterpret_cast<double*>(&jldoublenull);
255             value = *dp;
256         }
257         break;
258 
259         case execplan::CalpontSystemCatalog::DATE:
260         {
261             int d = joblist::DATENULL;
262             value = d;
263         }
264         break;
265 
266         case execplan::CalpontSystemCatalog::DATETIME:
267         {
268             long long d = joblist::DATETIMENULL;
269             value = d;
270         }
271         break;
272 
273         case execplan::CalpontSystemCatalog::TIME:
274         {
275             long long d = joblist::TIMENULL;
276             value = d;
277         }
278         break;
279 
280         case execplan::CalpontSystemCatalog::TIMESTAMP:
281         {
282             long long d = joblist::TIMESTAMPNULL;
283             value = d;
284         }
285         break;
286 
287         case execplan::CalpontSystemCatalog::CHAR:
288         {
289             std::string charnull;
290 
291             if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE)
292             {
293                 //charnull = joblist::CHAR1NULL;
294                 charnull = "\376";
295                 value = charnull;
296             }
297             else if (colType.colWidth == execplan::CalpontSystemCatalog::TWO_BYTE)
298             {
299                 //charnull = joblist::CHAR2NULL;
300                 charnull = "\377\376";
301                 value = charnull;
302             }
303             else if (colType.colWidth <= execplan::CalpontSystemCatalog::FOUR_BYTE)
304             {
305                 //charnull = joblist::CHAR4NULL;
306                 charnull = "\377\377\377\376";
307                 value = charnull;
308             }
309             else
310             {
311                 WriteEngine::Token nullToken;
312                 value = nullToken;
313             }
314 
315         }
316         break;
317 
318         case execplan::CalpontSystemCatalog::VARCHAR:
319         {
320             std::string charnull;
321 
322             if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE)
323             {
324                 //charnull = joblist::CHAR2NULL;
325                 charnull = "\377\376";
326                 value = charnull;
327             }
328             else if (colType.colWidth < execplan::CalpontSystemCatalog::FOUR_BYTE)
329             {
330                 //charnull = joblist::CHAR4NULL;
331                 charnull = "\377\377\377\376";
332                 value = charnull;
333             }
334             else
335             {
336                 WriteEngine::Token nullToken;
337                 value = nullToken;
338             }
339 
340         }
341         break;
342 
343         case execplan::CalpontSystemCatalog::BLOB:
344         case execplan::CalpontSystemCatalog::TEXT:
345         case execplan::CalpontSystemCatalog::VARBINARY:
346         {
347             std::string charnull;
348 
349             if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE)
350             {
351                 //charnull = joblist::CHAR2NULL;
352                 charnull = "\377\376";
353                 value = charnull;
354             }
355             else if (colType.colWidth < execplan::CalpontSystemCatalog::FOUR_BYTE)
356             {
357                 //charnull = joblist::CHAR4NULL;
358                 charnull = "\377\377\377\376";
359                 value = charnull;
360             }
361             else
362             {
363                 WriteEngine::Token nullToken;
364                 value = nullToken;
365             }
366 
367         }
368         break;
369 
370 
371         default:
372             throw std::runtime_error("getNullValueForType: unkown column data type");
373             break;
374 
375     }
376 
377     return value;
378 }
379 
convertDataType(int dataType)380 inline int convertDataType(int dataType)
381 {
382     int calpontDataType;
383 
384     switch (dataType)
385     {
386         case ddlpackage::DDL_CHAR:
387             calpontDataType = execplan::CalpontSystemCatalog::CHAR;
388             break;
389 
390         case ddlpackage::DDL_VARCHAR:
391             calpontDataType = execplan::CalpontSystemCatalog::VARCHAR;
392             break;
393 
394         case ddlpackage::DDL_VARBINARY:
395             calpontDataType = execplan::CalpontSystemCatalog::VARBINARY;
396             break;
397 
398         case ddlpackage::DDL_BIT:
399             calpontDataType = execplan::CalpontSystemCatalog::BIT;
400             break;
401 
402         case ddlpackage::DDL_REAL:
403         case ddlpackage::DDL_DECIMAL:
404         case ddlpackage::DDL_NUMERIC:
405         case ddlpackage::DDL_NUMBER:
406             calpontDataType = execplan::CalpontSystemCatalog::DECIMAL;
407             break;
408 
409         case ddlpackage::DDL_FLOAT:
410             calpontDataType = execplan::CalpontSystemCatalog::FLOAT;
411             break;
412 
413         case ddlpackage::DDL_DOUBLE:
414             calpontDataType = execplan::CalpontSystemCatalog::DOUBLE;
415             break;
416 
417         case ddlpackage::DDL_INT:
418         case ddlpackage::DDL_INTEGER:
419             calpontDataType = execplan::CalpontSystemCatalog::INT;
420             break;
421 
422         case ddlpackage::DDL_BIGINT:
423             calpontDataType = execplan::CalpontSystemCatalog::BIGINT;
424             break;
425 
426         case ddlpackage::DDL_MEDINT:
427             calpontDataType = execplan::CalpontSystemCatalog::MEDINT;
428             break;
429 
430         case ddlpackage::DDL_SMALLINT:
431             calpontDataType = execplan::CalpontSystemCatalog::SMALLINT;
432             break;
433 
434         case ddlpackage::DDL_TINYINT:
435             calpontDataType = execplan::CalpontSystemCatalog::TINYINT;
436             break;
437 
438         case ddlpackage::DDL_DATE:
439             calpontDataType = execplan::CalpontSystemCatalog::DATE;
440             break;
441 
442         case ddlpackage::DDL_DATETIME:
443             calpontDataType = execplan::CalpontSystemCatalog::DATETIME;
444             break;
445 
446         case ddlpackage::DDL_TIME:
447             calpontDataType = execplan::CalpontSystemCatalog::TIME;
448             break;
449 
450         case ddlpackage::DDL_TIMESTAMP:
451             calpontDataType = execplan::CalpontSystemCatalog::TIMESTAMP;
452             break;
453 
454         case ddlpackage::DDL_CLOB:
455             calpontDataType = execplan::CalpontSystemCatalog::CLOB;
456             break;
457 
458         case ddlpackage::DDL_BLOB:
459             calpontDataType = execplan::CalpontSystemCatalog::BLOB;
460             break;
461 
462         case ddlpackage::DDL_TEXT:
463             calpontDataType = execplan::CalpontSystemCatalog::TEXT;
464             break;
465 
466         case ddlpackage::DDL_UNSIGNED_TINYINT:
467             calpontDataType = execplan::CalpontSystemCatalog::UTINYINT;
468             break;
469 
470         case ddlpackage::DDL_UNSIGNED_SMALLINT:
471             calpontDataType = execplan::CalpontSystemCatalog::USMALLINT;
472             break;
473 
474         case ddlpackage::DDL_UNSIGNED_MEDINT:
475             calpontDataType = execplan::CalpontSystemCatalog::UMEDINT;
476             break;
477 
478         case ddlpackage::DDL_UNSIGNED_INT:
479             calpontDataType = execplan::CalpontSystemCatalog::UINT;
480             break;
481 
482         case ddlpackage::DDL_UNSIGNED_BIGINT:
483             calpontDataType = execplan::CalpontSystemCatalog::UBIGINT;
484             break;
485 
486         case ddlpackage::DDL_UNSIGNED_DECIMAL:
487         case ddlpackage::DDL_UNSIGNED_NUMERIC:
488             calpontDataType = execplan::CalpontSystemCatalog::UDECIMAL;
489             break;
490 
491         case ddlpackage::DDL_UNSIGNED_FLOAT:
492             calpontDataType = execplan::CalpontSystemCatalog::UFLOAT;
493             break;
494 
495         case ddlpackage::DDL_UNSIGNED_DOUBLE:
496             calpontDataType = execplan::CalpontSystemCatalog::UDOUBLE;
497             break;
498 
499         default:
500             throw runtime_error("Unsupported datatype!");
501 
502     }
503 
504     return calpontDataType;
505 }
506 
findColumnData(uint32_t sessionID,execplan::CalpontSystemCatalog::TableName & systableName,const std::string & colName,DDLColumn & sysCol)507 inline void findColumnData(uint32_t sessionID, execplan::CalpontSystemCatalog::TableName& systableName,
508                            const std::string& colName, DDLColumn& sysCol)
509 {
510     ColumnList columns;
511     ColumnList::const_iterator column_iterator;
512     std::string err;
513 
514     try
515     {
516         getColumnsForTable(sessionID, systableName.schema, systableName.table, columns);
517         column_iterator = columns.begin();
518 
519         while (column_iterator != columns.end())
520         {
521             sysCol = *column_iterator;
522             boost::to_lower(sysCol.tableColName.column);
523 
524             if (colName == sysCol.tableColName.column)
525             {
526                 break;
527             }
528 
529             ++column_iterator;
530         }
531     }
532     catch (exception& ex)
533     {
534         err = ex.what();
535         throw std::runtime_error(err);
536     }
537     catch (...)
538     {
539         err = "findColumnData:Unknown exception caught";
540         throw std::runtime_error(err);
541     }
542 }
543 
convertRidToColumn(uint64_t & rid,unsigned & dbRoot,unsigned & partition,unsigned & segment,unsigned filesPerColumnPartition,unsigned extentsPerSegmentFile,unsigned extentRows,unsigned startDBRoot,unsigned dbrootCnt)544 inline void convertRidToColumn(uint64_t& rid, unsigned& dbRoot, unsigned& partition,
545                                unsigned& segment, unsigned filesPerColumnPartition,
546                                unsigned  extentsPerSegmentFile, unsigned extentRows,
547                                unsigned startDBRoot, unsigned dbrootCnt)
548 {
549     partition = rid / (filesPerColumnPartition * extentsPerSegmentFile * extentRows);
550 
551     segment = (((rid % (filesPerColumnPartition * extentsPerSegmentFile * extentRows)) / extentRows)) % filesPerColumnPartition;
552 
553     dbRoot = ((startDBRoot - 1 + segment) % dbrootCnt) + 1;
554 
555     //Calculate the relative rid for this segment file
556     uint64_t relRidInPartition = rid - ((uint64_t)partition * (uint64_t)filesPerColumnPartition * (uint64_t)extentsPerSegmentFile * (uint64_t)extentRows);
557     idbassert(relRidInPartition <= (uint64_t)filesPerColumnPartition * (uint64_t)extentsPerSegmentFile * (uint64_t)extentRows);
558     uint32_t numExtentsInThisPart = relRidInPartition / extentRows;
559     unsigned numExtentsInThisSegPart = numExtentsInThisPart / filesPerColumnPartition;
560     uint64_t relRidInThisExtent = relRidInPartition - numExtentsInThisPart * extentRows;
561     rid = relRidInThisExtent +  numExtentsInThisSegPart * extentRows;
562 }
563 
564 }
565 #undef EXPORT
566 #endif
567 
568