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 #include <string>
19 #include <stdexcept>
20 #include <typeinfo>
21 using namespace std;
22
23 #include <cppunit/extensions/HelperMacros.h>
24
25 #include<sstream>
26 #include<exception>
27 #include<iostream>
28 #include <unistd.h>
29
30 #include "messagequeue.h"
31 #include "bytestream.h"
32 using namespace messageqcpp;
33
34 #include "calpontselectexecutionplan.h"
35 #include "simplefilter.h"
36 #include "simplecolumn.h"
37 #include "expressionparser.h"
38 #include "constantcolumn.h"
39 #include "treenode.h"
40 #include "operator.h"
41 #include "arithmeticcolumn.h"
42 #include "aggregatecolumn.h"
43 #include "selectfilter.h"
44
45 extern "C" char* cplus_demangle_with_style(const char*, int, int);
46 extern "C" void init_demangler(int, int, int);
47
48 using namespace execplan;
49
50 class ExecPlanTest : public CppUnit::TestFixture
51 {
52
53 CPPUNIT_TEST_SUITE( ExecPlanTest );
54
55 CPPUNIT_TEST( selectExecutionPlan_15 );
56
57 CPPUNIT_TEST_SUITE_END();
58
59 private:
60 public:
61
walkfnString(const ParseTree * n)62 static void walkfnString(const ParseTree* n)
63 {
64 char* r;
65 static bool is_init = false;
66 const char* mname = typeid(*(n->data())).name();
67
68 if (!is_init)
69 {
70 ::init_demangler(0, 0, 0);
71 is_init = true;
72 }
73
74 r = ::cplus_demangle_with_style(mname, 7, 27);
75
76 if (r != 0)
77 {
78 //cout << "mangle: " << mname << " demangle: " << r << endl;
79 ::free(r);
80 }
81
82 if (typeid(*(n->data())) == typeid(SimpleFilter))
83 {
84 cout << "SimpleFilter: " << endl;
85 const SimpleFilter* sf = dynamic_cast<SimpleFilter*>(n->data());
86 const ReturnedColumn* lhs = sf->lhs();
87 const ReturnedColumn* rhs = sf->rhs();
88 const Operator* op = sf->op();
89 cout << '\t' << lhs->data() << ' ' << op->data() << ' ' << rhs->data();
90 cout << endl << "\t\t";
91
92 if (typeid(*lhs) == typeid(SimpleColumn))
93 {
94 cout << "SimpleColumn: " << lhs->data() << " / ";
95 }
96 else if (typeid(*lhs) == typeid(ConstantColumn))
97 {
98 cout << "ConstantColumn: " << lhs->data() << " / ";
99 }
100 else
101 {
102 cout << "UNK: " << lhs->data() << " / ";
103 }
104
105 cout << "Operator: " << op->data() << " / ";
106
107 if (typeid(*rhs) == typeid(SimpleColumn))
108 {
109 cout << "SimpleColumn: " << rhs->data();
110 }
111 else if (typeid(*rhs) == typeid(ConstantColumn))
112 {
113 cout << "ConstantColumn: " << rhs->data();
114 }
115 else
116 {
117 cout << "UNK: " << rhs->data();
118 }
119 }
120 else if (typeid(*(n->data())) == typeid(Operator))
121 {
122 cout << "Operator: ";
123 const Operator* op = dynamic_cast<Operator*>(n->data());
124 cout << '\t' << op->data();
125 }
126 else
127 {
128 cout << mname << " -x-: ";
129 }
130
131 cout << endl;
132 }
133
setUp()134 void setUp()
135 {
136 }
137
tearDown()138 void tearDown()
139 {
140 }
141
selectExecutionPlan_15()142 void selectExecutionPlan_15()
143 {
144
145 cout <<
146 "SQL: \
147 create view revenue:s (supplier_no, total_revenue) as \
148 select \
149 l_suppkey, \
150 sum(l_extendedprice * (1 - l_discount)) \
151 from \
152 lineitem \
153 where \
154 l_shipdate >= date ':1' \
155 and l_shipdate < date ':1' + interval '3' month \
156 group by \
157 l_suppkey; \
158 \
159 select \
160 s_suppkey, \
161 s_name, \
162 s_address, \
163 s_phone, \
164 total_revenue \
165 from \
166 supplier, \
167 revenue:s \
168 where \
169 s_suppkey = supplier_no \
170 and total_revenue = ( \
171 select \
172 max(total_revenue) \
173 from \
174 revenue:s \
175 ) \
176 order by \
177 s_suppkey; \
178 \
179 drop view revenue:s; \
180 " << endl;
181
182 /* ------------The create view statement is being re-written as an inline view ----- */
183 /* ------------ (dynamic table) to be used in a from cluase. ----- */
184
185 CalpontSelectExecutionPlan* csep = new CalpontSelectExecutionPlan();
186 CalpontSelectExecutionPlan::ReturnedColumnList colList;
187 CalpontSelectExecutionPlan::GroupByColumnList groupbyList;
188 CalpontSelectExecutionPlan::OrderByColumnList orderbyList;
189 ParseTree* filterList;
190
191 // returned columns
192 //SimpleColumn l_suppkey("tpch.lineitem.l_suppkey");
193 SimpleColumn* l_suppkey = new SimpleColumn("tpch.lineitem.l_suppkey");
194 AggregateColumn* total_revenue = new AggregateColumn();
195 total_revenue->functionName("sum");
196 total_revenue->alias("total_revenue");
197 ArithmeticColumn* a1 = new ArithmeticColumn ("l_extenedprice * (1 - l_discount)");
198 total_revenue->functionParms(a1);
199
200 // Create the Projection
201 colList.push_back(l_suppkey);
202 colList.push_back(total_revenue);
203
204 // Filter columns
205 SimpleColumn l_shipdate("tpch.lineitem.l_shipdate");
206 //SimpleColumn l_shipmode0("tpch.lineitem.l_shipmode");
207 //SimpleColumn l_shipmode1("tpch.lineitem.l_shipmode");
208 //SimpleColumn l_commitdate("tpch.lineitem.l_commitdate");
209 //SimpleColumn l_receiptdate("tpch.lineitem.l_receiptdate");
210 //SimpleColumn l_receiptdate1("tpch.lineitem.l_receiptdate");
211
212
213 // filters
214 CalpontSelectExecutionPlan::Parser parser;
215 std::vector<Token> tokens;
216
217 //tokens.push_back(Token(new Operator("(")));
218 //tokens.push_back(Token(new Operator(")")));
219
220 tokens.push_back(Token(new SimpleFilter(new Operator(">="),
221 new SimpleColumn(l_shipdate),
222 new ConstantColumn("06/01/2005"))));
223
224 tokens.push_back(Token(new Operator("and")));
225
226 tokens.push_back(Token(new SimpleFilter(new Operator("<"),
227 new SimpleColumn(l_shipdate),
228 new ConstantColumn("07/01/2005"))));
229
230 // old below
231 filterList = parser.parse(tokens.begin(), tokens.end());
232
233 // draw filterList tree
234 filterList->drawTree("selectExecutionPlan_15sub.dot");
235
236 // Build Group By List
237 SimpleColumn* l_suppkey2 = new SimpleColumn("tpch.lineitem.l_suppkey");
238 groupbyList.push_back(l_suppkey2);
239
240 // calpont execution plan
241 csep->returnedCols (colList);
242 csep->filters (filterList);
243
244 csep->location (CalpontSelectExecutionPlan::FROM); // Use scope resolution to use enum.
245
246 cout << "\nCalpont Execution Plan:" << endl;
247 cout << *csep << endl;
248 cout << " --- end of test 15 ---" << endl;
249
250 /* ------ This is the begining of the outer query ---------------------- */
251 /* ------ This is the begining of the outer query ---------------------- */
252
253
254 CalpontSelectExecutionPlan* csep_parent = new CalpontSelectExecutionPlan();
255 cout << "********* I'm ok to here 01 ***************" << endl;
256 CalpontSelectExecutionPlan::ReturnedColumnList colList2;
257 CalpontSelectExecutionPlan::GroupByColumnList groupbyList2;
258 cout << "********* I'm ok to here 02 ***************" << endl;
259 CalpontSelectExecutionPlan::OrderByColumnList orderbyList2;
260 CalpontSelectExecutionPlan::SelectList subSelectList2;
261 //`ParseTree* filterList2;
262
263 cout << "********* I'm ok to here 1 ***************" << endl;
264 // returned columns
265 SimpleColumn* s_suppkey = new SimpleColumn ("tpch.supplier.s_suppkey");
266 SimpleColumn* s_name = new SimpleColumn("tpch.supplier.s_name");
267 SimpleColumn* s_address = new SimpleColumn("tpch.supplier.s_address");
268 SimpleColumn* s_phone = new SimpleColumn("tpch.supplier.s_phone");
269 cout << "********* I'm ok to here 1a ***************" << endl;
270 AggregateColumn* s_total_revenue = new AggregateColumn();
271 cout << "********* I'm ok to here 1b ***************" << endl;
272 s_total_revenue->functionName("sum");
273 ArithmeticColumn* a5 = new ArithmeticColumn ("o_orderpriority = '2-HIGH' THEN 1 ELSE 0 END )");
274 cout << "********* I'm ok to here 1c ***************" << endl;
275 s_total_revenue->functionParms(a5);
276
277 // Create the Projection
278 cout << "********* I'm ok to here 1d ***************" << endl;
279 colList2.push_back(s_suppkey);
280 colList2.push_back(s_name);
281 colList2.push_back(s_address);
282 colList2.push_back(s_phone);
283 colList2.push_back(s_total_revenue);
284 cout << "********* I'm ok to here 1e ***************" << endl;
285
286 /* ------ This is the begining of the query filter ---------------------- */
287 /* ------ This is the begining of the query filter ---------------------- */
288
289 //std::vector<Token> tokens_n;
290 CalpontSelectExecutionPlan::FilterTokenList regFilterTokenList;
291 SimpleFilter* f1 = new SimpleFilter ( new Operator("="),
292 new SimpleColumn ("tpch.supplier.s_suppkey"),
293 new SimpleColumn ("tpch.supplier.s_supplier_no"));
294
295 regFilterTokenList.push_back(f1);
296 regFilterTokenList.push_back(new Operator("and"));
297
298
299 cout << "********* I'm ok to here 1 ***************" << endl;
300 //Sub select filter
301 CalpontSelectExecutionPlan* subcsep =
302 new CalpontSelectExecutionPlan(CalpontSelectExecutionPlan::WHERE);
303
304 //subselect return column(s)
305 CalpontSelectExecutionPlan::ReturnedColumnList subColList;
306
307 ArithmeticColumn* sc1 = new ArithmeticColumn ("max(total_revenue)");
308 //CalpontSelectExecutionPlan::SelectList subSelectList;
309
310 subColList.push_back(sc1);
311 subcsep->returnedCols(subColList);
312 cout << "********* I'm ok to here 2 ***************" << endl;
313
314 //subselect Filters
315 //CalpontSelectExecutionPlan::FilterTokenList subFilterTokenList;
316 SelectFilter* f2 = new SelectFilter (new SimpleColumn ("tpch.revenue.total_revenue"),
317 new Operator("="),
318 subcsep);
319
320 regFilterTokenList.push_back(f2);
321
322
323 cout << "********* I'm ok to here 3 ***************" << endl;
324 // Filter columns
325 //SimpleColumn l_shipmode0("tpch.lineitem.l_shipmode");
326 // *** Already creted via regFilterTokenList object ****
327
328 // filters
329 //CalpontSelectExecutionPlan::Parser parser;
330 //std::vector<Token> tokens;
331 // *** Already creted via regFilterTokenList object ****
332
333 //tokens.push_back(Token(new Operator("(")));
334 //tokens.push_back(Token(new Operator(")")));
335
336 //tokens.push_back(Token(new SimpleFilter(new Operator("="),
337 // new SimpleColumn(l_shipmode),
338 // new ConstantColumn("1"))));
339
340 //tokens.push_back(Token(new Operator("and")));
341
342 //tokens.push_back(Token(new SimpleFilter(new Operator("="),
343 // new SimpleColumn(l_shipmode),
344 // new ConstantColumn("2"))));
345
346
347 // old below
348 // filterList = parser.parse(tokens.begin(), tokens.end());
349
350 // draw filterList tree
351 //filterList->drawTree("selectExecutionPlan_15n.dot");
352
353 // Build Group By List
354 //SimpleColumn *l_shipmode2 = new SimpleColumn("tpch.lineitem.l_shipmode");
355 //groupbyList.push_back(l_shipmode2);
356
357 // Build Order By List
358 SimpleColumn* s_suppkey3 = new SimpleColumn("tpch.supplier.s_suppkey");
359 orderbyList.push_back(s_suppkey3);
360
361 // calpont execution plan
362 csep_parent->returnedCols (colList2);
363 csep_parent->filterTokenList(regFilterTokenList);
364 csep_parent->orderByCols(orderbyList);
365
366 cout << "********* I'm ok to here 4 ***************" << endl;
367 // draw filterList tree
368 //csep_parent->filterTokenList->drawTree("selectExecutionPlan_15.dot");
369 ParseTree* pt = const_cast<ParseTree*>(csep_parent->filters());
370 pt->drawTree("selectExecutionPlan_15.dot");
371
372 cout << "\nCalpont Execution Plan:" << endl;
373 cout << csep << endl;
374 cout << " --- end of test 15 ---" << endl;
375
376 filterList->walk(walkfnString);
377
378 }
379
380 };
381
382 CPPUNIT_TEST_SUITE_REGISTRATION( ExecPlanTest );
383
384 #include <cppunit/extensions/TestFactoryRegistry.h>
385 #include <cppunit/ui/text/TestRunner.h>
386
main(int argc,char ** argv)387 int main( int argc, char** argv)
388 {
389 CppUnit::TextUi::TestRunner runner;
390 CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
391 runner.addTest( registry.makeTest() );
392 bool wasSuccessful = runner.run( "", false );
393 return (wasSuccessful ? 0 : 1);
394 }
395
396
397