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