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  *
20  * $Id: objectreader.cpp 9559 2013-05-22 17:58:13Z xlou $
21  *
22  ****************************************************************************/
23 
24 /*
25  * Implements ObjectReader
26  */
27 
28 #include <unistd.h>
29 #include <string>
30 #include <sstream>
31 
32 #include "treenode.h"
33 #include "returnedcolumn.h"
34 #include "aggregatecolumn.h"
35 #include "udafcolumn.h"
36 #include "arithmeticcolumn.h"
37 #include "constantcolumn.h"
38 #include "functioncolumn.h"
39 #include "rowcolumn.h"
40 #include "simplecolumn.h"
41 #include "simplecolumn_int.h"
42 #include "simplecolumn_uint.h"
43 #include "simplecolumn_decimal.h"
44 #include "filter.h"
45 #include "existsfilter.h"
46 #include "selectfilter.h"
47 #include "simplefilter.h"
48 #include "constantfilter.h"
49 #include "simplescalarfilter.h"
50 #include "operator.h"
51 #include "arithmeticoperator.h"
52 #include "windowfunctioncolumn.h"
53 #include "logicoperator.h"
54 #include "predicateoperator.h"
55 #include "pseudocolumn.h"
56 #include "treenodeimpl.h"
57 #include "calpontexecutionplan.h"
58 #include "calpontselectexecutionplan.h"
59 #include "groupconcatcolumn.h"
60 #include "outerjoinonfilter.h"
61 
62 #include "bytestream.h"
63 #include "expressionparser.h"
64 #include "objectreader.h"
65 
66 using namespace std;
67 
68 namespace execplan
69 {
70 
createTreeNode(messageqcpp::ByteStream & b)71 TreeNode* ObjectReader::createTreeNode(messageqcpp::ByteStream& b)
72 {
73 
74     CLASSID id = ZERO;
75     TreeNode* ret;
76 
77     b.peek(reinterpret_cast<messageqcpp::ByteStream::byte&>(id));
78 
79     switch (id)
80     {
81         case TREENODEIMPL:
82             ret = new TreeNodeImpl();
83             break;
84 
85         case SIMPLECOLUMN:
86             ret = new SimpleColumn();
87             break;
88 
89         case SIMPLECOLUMN_INT2:
90             ret = new SimpleColumn_INT<2>();
91             break;
92 
93         case SIMPLECOLUMN_INT4:
94             ret = new SimpleColumn_INT<4>();
95             break;
96 
97         case SIMPLECOLUMN_INT8:
98             ret = new SimpleColumn_INT<8>();
99             break;
100 
101         case SIMPLECOLUMN_INT1:
102             ret = new SimpleColumn_INT<1>();
103             break;
104 
105         case SIMPLECOLUMN_UINT2:
106             ret = new SimpleColumn_UINT<2>();
107             break;
108 
109         case SIMPLECOLUMN_UINT4:
110             ret = new SimpleColumn_UINT<4>();
111             break;
112 
113         case SIMPLECOLUMN_UINT8:
114             ret = new SimpleColumn_UINT<8>();
115             break;
116 
117         case SIMPLECOLUMN_UINT1:
118             ret = new SimpleColumn_UINT<1>();
119             break;
120 
121         case SIMPLECOLUMN_DECIMAL2:
122             ret = new SimpleColumn_Decimal<2>();
123             break;
124 
125         case SIMPLECOLUMN_DECIMAL4:
126             ret = new SimpleColumn_Decimal<4>();
127             break;
128 
129         case SIMPLECOLUMN_DECIMAL8:
130             ret = new SimpleColumn_Decimal<8>();
131             break;
132 
133         case SIMPLECOLUMN_DECIMAL1:
134             ret = new SimpleColumn_Decimal<1>();
135             break;
136 
137         case AGGREGATECOLUMN:
138             ret = new AggregateColumn();
139             break;
140 
141         case GROUPCONCATCOLUMN:
142             ret = new GroupConcatColumn();
143             break;
144 
145         case UDAFCOLUMN:
146             ret = new UDAFColumn();
147             break;
148 
149         case ARITHMETICCOLUMN:
150             ret = new ArithmeticColumn();
151             break;
152 
153         case CONSTANTCOLUMN:
154             ret = new ConstantColumn();
155             break;
156 
157         case FUNCTIONCOLUMN:
158             ret = new FunctionColumn();
159             break;
160 
161         case ROWCOLUMN:
162             ret = new RowColumn();
163             break;
164 
165         case WINDOWFUNCTIONCOLUMN:
166             ret = new WindowFunctionColumn();
167             break;
168 
169         case PSEUDOCOLUMN:
170             ret = new PseudoColumn();
171             break;
172 
173         case FILTER:
174             ret = new Filter();
175             break;
176 
177         case EXISTSFILTER:
178             ret = new ExistsFilter();
179             break;
180 
181         case SELECTFILTER:
182             ret = new SelectFilter();
183             break;
184 
185         case SIMPLEFILTER:
186             ret = new SimpleFilter();
187             break;
188 
189         case CONSTANTFILTER:
190             ret = new ConstantFilter();
191             break;
192 
193         case SIMPLESCALARFILTER:
194             ret = new SimpleScalarFilter();
195             break;
196 
197         case OUTERJOINONFILTER:
198             ret = new OuterJoinOnFilter();
199             break;
200 
201         case OPERATOR:
202             ret = new Operator();
203             break;
204 
205         case ARITHMETICOPERATOR:
206             ret = new ArithmeticOperator();
207             break;
208 
209         case LOGICOPERATOR:
210             ret = new LogicOperator();
211             break;
212 
213         case PREDICATEOPERATOR:
214             ret = new PredicateOperator();
215             break;
216 
217         case NULL_CLASS:
218             b >> (id_t&) id;   //eat the ID
219             return NULL;
220 
221         default:
222         {
223             ostringstream oss;
224             oss << "Bad type: " << (int)id << ". Stream out of sync? (1)";
225             throw UnserializeException(oss.str());
226             break;
227         }
228     }
229 
230     ret->unserialize(b);
231     return ret;
232 }
233 
createExecutionPlan(messageqcpp::ByteStream & b)234 CalpontExecutionPlan* ObjectReader::createExecutionPlan(messageqcpp::ByteStream& b)
235 {
236     CLASSID id = ZERO;
237     CalpontExecutionPlan* ret;
238 
239     b.peek(reinterpret_cast<messageqcpp::ByteStream::byte&>(id));
240 
241     switch (id)
242     {
243         case CALPONTSELECTEXECUTIONPLAN:
244             ret = new CalpontSelectExecutionPlan();
245             break;
246 
247         case NULL_CLASS:
248             b >> reinterpret_cast<id_t&>(id);
249             return NULL;
250 
251         default:
252         {
253             ostringstream oss;
254             oss << "Bad type: " << (int)id << ". Stream out of sync? (2)";
255             throw UnserializeException(oss.str());
256             break;
257         }
258     }
259 
260     ret->unserialize(b);
261     return ret;
262 }
263 
writeParseTree(const ParseTree * tree,messageqcpp::ByteStream & b)264 void ObjectReader::writeParseTree(const ParseTree* tree, messageqcpp::ByteStream& b)
265 {
266     if (tree == NULL)
267     {
268         b << (id_t) NULL_CLASS;
269         return;
270     }
271 
272     b << (id_t) PARSETREE;
273     writeParseTree(tree->left(), b);
274     writeParseTree(tree->right(), b);
275 
276     if (tree->data() == NULL)
277         b << (id_t) NULL_CLASS;
278     else
279         tree->data()->serialize(b);
280 }
281 
createParseTree(messageqcpp::ByteStream & b)282 ParseTree* ObjectReader::createParseTree(messageqcpp::ByteStream& b)
283 {
284     CLASSID id = ZERO;
285     ParseTree* ret;
286 
287     b >> (id_t&) id;
288 
289     if (id == NULL_CLASS)
290         return NULL;
291 
292     if (id != PARSETREE)
293         throw UnserializeException("Not a ParseTree");
294 
295     ret = new ParseTree();
296     ret->left(createParseTree(b));
297     ret->right(createParseTree(b));
298     ret->data(createTreeNode(b));
299     return ret;
300 }
301 
checkType(messageqcpp::ByteStream & b,const CLASSID id)302 void ObjectReader::checkType(messageqcpp::ByteStream& b, const CLASSID id)
303 {
304     CLASSID readId = ZERO;
305 
306     b >> (id_t&) readId;
307 
308     if (readId != id)
309         switch (id)
310         {
311             case TREENODEIMPL:
312                 throw UnserializeException("Not a TreeNodeImpl");
313 
314             case RETURNEDCOLUMN:
315                 throw UnserializeException("Not a ReturnedColumn");
316 
317             case SIMPLECOLUMN:
318                 throw UnserializeException("Not a SimpleColumn");
319 
320             case AGGREGATECOLUMN:
321                 throw UnserializeException("Not an AggregateColumn");
322 
323             case ARITHMETICCOLUMN:
324                 throw UnserializeException("Not an ArithmeticColumn");
325 
326             case CONSTANTCOLUMN:
327                 throw UnserializeException("Not a ConstantColumn");
328 
329             case FUNCTIONCOLUMN:
330                 throw UnserializeException("Not a FunctionColumn");
331 
332             case ROWCOLUMN:
333                 throw UnserializeException("Not a RowColumn");
334 
335             case WINDOWFUNCTIONCOLUMN:
336                 throw UnserializeException("Not a WindowFunctionColumn");
337 
338             case PSEUDOCOLUMN:
339                 throw UnserializeException("Not a PseudoColumn");
340 
341             case FILTER:
342                 throw UnserializeException("Not a Filter");
343 
344             case CONDITIONFILTER:
345                 throw UnserializeException("Not a ConditionFilter");
346 
347             case EXISTSFILTER:
348                 throw UnserializeException("Not an ExistsFilter");
349 
350             case SELECTFILTER:
351                 throw UnserializeException("Not a SelectFilter");
352 
353             case SIMPLEFILTER:
354                 throw UnserializeException("Not a SimpleFilter");
355 
356             case CONSTANTFILTER:
357                 throw UnserializeException("Not a ConstantFilter");
358 
359             case OPERATOR:
360                 throw UnserializeException("Not an Operator");
361 
362             case PARSETREE:
363                 throw UnserializeException("Not an ParseTree");
364 
365             case CALPONTSELECTEXECUTIONPLAN:
366                 throw UnserializeException("Not a CalpontSelectExecutionPlan");
367 
368             case NULL_CLASS:
369                 throw UnserializeException("Not NULL");   // ??
370 
371             case MCSV1_CONTEXT:
372                 throw UnserializeException("Not a MCSV1_CONTEXT");
373 
374             default:
375                 throw UnserializeException("Bad id");
376         }
377 
378     return;
379 }
380 
UnserializeException(string msg)381 ObjectReader::UnserializeException::UnserializeException(string msg)
382 throw() : fWhat(msg)
383 {
384 }
385 
~UnserializeException()386 ObjectReader::UnserializeException::~UnserializeException() throw()
387 {
388 }
389 
what() const390 const char* ObjectReader::UnserializeException::what() const throw()
391 {
392     return fWhat.c_str();
393 }
394 
395 
396 }   /* namespace */
397