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 // $Id: tdriver-function.cpp 9210 2013-01-21 14:10:42Z rdempsey $
19 #include <iostream>
20 #include <list>
21 #include <sstream>
22 #include <pthread.h>
23 #include <iomanip>
24 #include <cppunit/extensions/HelperMacros.h>
25 #include <cppunit/extensions/TestFactoryRegistry.h>
26 #include <cppunit/ui/text/TestRunner.h>
27 
28 #include "wsdl.h"
29 #include "constantdatalist.h"
30 
31 #include "calpontsystemcatalog.h"
32 using namespace execplan;
33 
34 #include "functionoperation.h"
35 #include <boost/any.hpp>
36 #include <boost/function.hpp>
37 #include "bytestream.h"
38 #include <time.h>
39 #include <sys/time.h>
40 #include <cmath>
41 #include <boost/any.hpp>
42 #include <jobstep.h>
43 
44 #define DEBUG
45 
46 using namespace std;
47 using namespace joblist;
48 using namespace messageqcpp;
49 
50 
51 // void (*fp) (double, double);
52 
53 // Timer class used by this tdriver to output elapsed times, etc.
54 class Timer
55 {
56 public:
start(const string & message)57     void start(const string& message)
58     {
59         if (!fHeaderDisplayed)
60         {
61             header();
62             fHeaderDisplayed = true;
63         }
64 
65         gettimeofday(&fTvStart, 0);
66         cout << timestr() << "          Start " << message << endl;
67     }
68 
stop(const string & message)69     void stop(const string& message)
70     {
71         time_t now;
72         time(&now);
73         string secondsElapsed;
74         getTimeElapsed(secondsElapsed);
75         cout << timestr() << " " << secondsElapsed << " Stop  " << message << endl;
76     }
77 
Timer()78     Timer() : fHeaderDisplayed(false) {}
79 
80 private:
81 
82     struct timeval fTvStart;
83     bool fHeaderDisplayed;
84 
getTimeElapsed(string & seconds)85     double getTimeElapsed(string& seconds)
86     {
87         struct timeval tvStop;
88         gettimeofday(&tvStop, 0);
89         double secondsElapsed =
90             (tvStop.tv_sec + (tvStop.tv_usec / 1000000.0)) -
91             (fTvStart.tv_sec + (fTvStart.tv_usec / 1000000.0));
92         ostringstream oss;
93         oss << secondsElapsed;
94         seconds = oss.str();
95         seconds.resize(8, '0');
96         return secondsElapsed;
97     }
98 
timestr()99     string timestr()
100     {
101         struct tm tm;
102         struct timeval tv;
103 
104         gettimeofday(&tv, 0);
105         localtime_r(&tv.tv_sec, &tm);
106 
107         ostringstream oss;
108         oss << setfill('0')
109             << setw(2) << tm.tm_hour << ':'
110             << setw(2) << tm.tm_min << ':'
111             << setw(2) << tm.tm_sec	<< '.'
112             << setw(6) << tv.tv_usec
113             ;
114         return oss.str();
115     }
116 
header()117     void header()
118     {
119         cout << endl;
120         cout << "Time            Seconds  Activity" << endl;
121     }
122 };
123 
124 // Timer class used by this tdriver to output elapsed times, etc.
125 class MultiTimer
126 {
127 
128 
129 public:
130     void start(const string& message);
131     void stop(const string& message);
finish()132     void finish()
133     {
134 
135         // Calculate the total seconds elapsed.
136         struct timeval tvStop;
137         gettimeofday(&tvStop, 0);
138         double totalSeconds =
139             (tvStop.tv_sec + (tvStop.tv_usec / 1000000.0)) -
140             (fTvStart.tv_sec + (fTvStart.tv_usec / 1000000.0));
141 
142         cout << endl;
143         cout << "Seconds  Percentage  Calls      Description" << endl;
144 
145         // Add a last entry into the vector for total.
146         ProcessStats total;
147         total.fTotalSeconds = totalSeconds;
148         total.fProcess = "Total";
149         total.fStartCount = 1;
150         fProcessStats.push_back(total);
151 
152         for (uint32_t i = 0; i < fProcessStats.size(); i++)
153         {
154 
155             if (i == (fProcessStats.size() - 1))
156             {
157                 cout << endl;
158             }
159 
160             // Seconds.
161             string seconds;
162             ostringstream oss;
163             oss << fProcessStats[i].fTotalSeconds;
164             seconds = oss.str();
165             seconds.resize(7, '0');
166             cout << seconds << "  ";
167 
168             // Percentage.
169             string percentage;
170             ostringstream oss2;
171             oss2 << (fProcessStats[i].fTotalSeconds / totalSeconds) * 100.0;
172             percentage = oss2.str();
173             percentage.resize(5, ' ');
174             cout << percentage << "%      ";
175 
176             // Times Initiated.
177             ostringstream oss3;
178             oss3 << fProcessStats[i].fStartCount;
179             string timesInitiated = oss3.str();
180             timesInitiated.resize(10, ' ');
181             cout << timesInitiated << " ";
182 
183             // Description.
184             cout << fProcessStats[i].fProcess << endl;
185         }
186 
187 
188 
189     }
MultiTimer()190     MultiTimer() : fStarted(false) {};
191 
192 private:
193     class ProcessStats
194     {
195     public:
196 
197         string fProcess;
198         struct timeval fTvProcessStarted;
199         double fTotalSeconds;
200         long fStartCount;
201         long fStopCount;
202 
ProcessStats()203         ProcessStats() : fProcess(""), fTotalSeconds(0.0), fStartCount(0), fStopCount(0) {};
204 
processStart()205         void processStart()
206         {
207             gettimeofday(&fTvProcessStarted, 0);
208             fStartCount++;
209         }
210 
processStop()211         void processStop()
212         {
213             struct timeval tvStop;
214             gettimeofday(&tvStop, 0);
215             fStopCount++;
216             fTotalSeconds +=
217                 (tvStop.tv_sec + (tvStop.tv_usec / 1000000.0)) -
218                 (fTvProcessStarted.tv_sec + (fTvProcessStarted.tv_usec / 1000000.0));
219 
220         }
221     };
222 
223     struct timeval fTvStart;
224     vector <ProcessStats> fProcessStats;
225     bool fStarted;
226 };
227 
stop(const string & message)228 void MultiTimer::stop(const string& message)
229 {
230     bool found = false;
231     uint32_t idx = 0;
232 
233     for (uint32_t i = 0; i < fProcessStats.size(); i++)
234     {
235         if (fProcessStats[i].fProcess == message)
236         {
237             idx = i;
238             found = true;
239             break;
240         }
241     }
242 
243     if (!found)
244     {
245         throw std::runtime_error("MultiTimer::stop " + message + " called without calling start first.");
246     }
247 
248     fProcessStats[idx].processStop();
249 }
250 
start(const string & message)251 void MultiTimer::start(const string& message)
252 {
253     bool found = false;
254     uint32_t idx = 0;
255     ProcessStats processStats;
256 
257     if (!fStarted)
258     {
259         fStarted = true;
260         gettimeofday(&fTvStart, 0);
261     }
262 
263     for (uint32_t i = 0; i < fProcessStats.size(); i++)
264     {
265         if (fProcessStats[i].fProcess == message)
266         {
267             idx = i;
268             found = true;
269             break;
270         }
271     }
272 
273     if (!found)
274     {
275         fProcessStats.push_back(processStats);
276         idx = fProcessStats.size() - 1;
277     }
278 
279     fProcessStats[idx].fProcess = message;
280     fProcessStats[idx].processStart();
281 }
282 
283 class functionDriver : public CppUnit::TestFixture
284 {
285 
286     CPPUNIT_TEST_SUITE(functionDriver);
287     CPPUNIT_TEST(FUNCTION_TEST);
288     CPPUNIT_TEST_SUITE_END();
289 
290 private:
291     ResourceManager fRm;
292 
testDrdFunctions()293     void testDrdFunctions()
294     {
295         cout << endl;
296         cout << "double f(double) functions" << endl;
297         cout << "---------------------------" << endl;
298 
299         FunctionOperation* fop = FunctionOperation::instance();
300 
301         // functions to test
302         list<string> functionsToTest;
303         functionsToTest.push_back("abs");
304         functionsToTest.push_back("acos");
305         functionsToTest.push_back("asin");
306         functionsToTest.push_back("atan");
307         functionsToTest.push_back("ceil");
308         functionsToTest.push_back("cos");
309         functionsToTest.push_back("cosh");
310         functionsToTest.push_back("exp");
311         functionsToTest.push_back("floor");
312         functionsToTest.push_back("ln");
313         functionsToTest.push_back("log2");
314         functionsToTest.push_back("log10");
315         functionsToTest.push_back("sin");
316         functionsToTest.push_back("sinh");
317         functionsToTest.push_back("sqrt");
318         functionsToTest.push_back("tan");
319         functionsToTest.push_back("tanh");
320 
321         // type vector is the same for drd functions
322         vector<FunctionDataList::FuncDataListType> types;
323         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
324         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
325 
326         int numRows = 1;
327         DoubleElementType el0, el1;
328         list<string>::iterator it;
329 
330         for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
331         {
332             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
333             CPPUNIT_ASSERT(fp);
334             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
335             WSDL<DoubleElementType>* wsdlIn1 = new WSDL<DoubleElementType>(2, numRows, fRm);
336 
337             for (int i = 0; i < numRows; i++)
338             {
339                 el1.first = i;
340                 el1.second = (0.5);
341                 wsdlIn1->insert(el1);
342             }
343 
344             wsdlIn1->endOfInput();
345 
346             FunctionDataListSPtr listIn1(new FunctionDataList());
347             FunctionDataListSPtr listOut(new FunctionDataList());
348             FDLVec parms;
349             listOut->doubleDl(wsdlOut);
350             listIn1->doubleDl(wsdlIn1);
351             parms.push_back(listOut);
352             parms.push_back(listIn1);
353             fop->executeFunction(fop, fp, parms);
354             wsdlOut->endOfInput();
355 
356             int id0 = wsdlOut->getIterator();
357             int id1 = wsdlIn1->getIterator();
358 
359             for (int i = 0; i < numRows; i++)
360             {
361                 wsdlIn1->next(id1, &el1);
362                 wsdlOut->next(id0, &el0);
363                 cout << *it << "(" << el1.second << ")=" << el0.second << endl;
364             }
365         }
366     }
367 
testDrddFunctions()368     void testDrddFunctions()
369     {
370         cout << endl;
371         cout << "double f(double, double) functions" << endl;
372         cout << "---------------------------" << endl;
373 
374         FunctionOperation* fop = FunctionOperation::instance();
375 
376         list<string> functionsToTest;
377         functionsToTest.push_back("atan2");
378         functionsToTest.push_back("power");
379         functionsToTest.push_back("+");
380         functionsToTest.push_back("-");
381         functionsToTest.push_back("*");
382         functionsToTest.push_back("/");
383 
384         // type vector is the same for drdd functions
385         vector<FunctionDataList::FuncDataListType> types;
386         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
387         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
388         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
389 
390         int numRows = 1;
391         DoubleElementType el0, el1, el2;
392         list<string>::iterator it;
393 
394         for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
395         {
396             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
397             CPPUNIT_ASSERT(fp);
398             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
399             WSDL<DoubleElementType>* wsdlIn1 = new WSDL<DoubleElementType>(2, numRows, fRm);
400             WSDL<DoubleElementType>* wsdlIn2 = new WSDL<DoubleElementType>(2, numRows, fRm);
401 
402             for (int i = 0; i < numRows; i++)
403             {
404                 el1.first = i;
405                 el1.second = (0.5);
406                 wsdlIn1->insert(el1);
407                 wsdlIn2->insert(el1);  // the data in two list is the same
408             }
409 
410             wsdlIn1->endOfInput();
411             wsdlIn2->endOfInput();
412 
413             FunctionDataListSPtr listOut(new FunctionDataList());
414             FunctionDataListSPtr listIn1(new FunctionDataList());
415             FunctionDataListSPtr listIn2(new FunctionDataList());
416             FDLVec parms;
417             listOut->doubleDl(wsdlOut);
418             listIn1->doubleDl(wsdlIn1);
419             listIn2->doubleDl(wsdlIn2);
420             parms.push_back(listOut);
421             parms.push_back(listIn1);
422             parms.push_back(listIn2);
423             fop->executeFunction(fop, fp, parms);
424             wsdlOut->endOfInput();
425 
426             int id0 = wsdlOut->getIterator();
427             int id1 = wsdlIn1->getIterator();
428             int id2 = wsdlIn2->getIterator();
429 
430             for (int i = 0; i < numRows; i++)
431             {
432                 wsdlIn1->next(id1, &el1);
433                 wsdlIn2->next(id2, &el2);
434                 wsdlOut->next(id0, &el0);
435                 cout << *it << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
436             }
437         }
438     }
439 
testSrssFunctions()440     void testSrssFunctions()
441     {
442         cout << endl;
443         cout << "string f(string, string) functions" << endl;
444         cout << "---------------------------" << endl;
445 
446         FunctionOperation* fop = FunctionOperation::instance();
447 
448         list<string> functionsToTest;
449         functionsToTest.push_back("||");
450         functionsToTest.push_back("concat");
451 
452         // type vector is the same for drdd functions
453         vector<FunctionDataList::FuncDataListType> types;
454         types.push_back(FunctionDataList::STRING_LISTTYPE);
455         types.push_back(FunctionDataList::STRING_LISTTYPE);
456         types.push_back(FunctionDataList::STRING_LISTTYPE);
457 
458         int numRows = 1;
459         StringElementType el0, el1, el2;
460         list<string>::iterator it;
461 
462         for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
463         {
464             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
465             CPPUNIT_ASSERT(fp);
466             WSDL<StringElementType>* wsdlOut = new WSDL<StringElementType>(1, numRows, fRm);
467             WSDL<StringElementType>* wsdlIn1 = new WSDL<StringElementType>(2, numRows, fRm);
468             WSDL<StringElementType>* wsdlIn2 = new WSDL<StringElementType>(2, numRows, fRm);
469 
470             for (int i = 0; i < numRows; i++)
471             {
472                 el1.first = i;
473                 el1.second = "abc";
474                 wsdlIn1->insert(el1);
475                 wsdlIn2->insert(el1);  // the data in two list is the same
476             }
477 
478             wsdlIn1->endOfInput();
479             wsdlIn2->endOfInput();
480 
481             FunctionDataListSPtr listOut(new FunctionDataList());
482             FunctionDataListSPtr listIn1(new FunctionDataList());
483             FunctionDataListSPtr listIn2(new FunctionDataList());
484             FDLVec parms;
485             listOut->stringDl(wsdlOut);
486             listIn1->stringDl(wsdlIn1);
487             listIn2->stringDl(wsdlIn2);
488             parms.push_back(listOut);
489             parms.push_back(listIn1);
490             parms.push_back(listIn2);
491             fop->executeFunction(fop, fp, parms);
492             wsdlOut->endOfInput();
493 
494             int id0 = wsdlOut->getIterator();
495             int id1 = wsdlIn1->getIterator();
496             int id2 = wsdlIn2->getIterator();
497 
498             for (int i = 0; i < numRows; i++)
499             {
500                 wsdlIn1->next(id1, &el1);
501                 wsdlIn2->next(id2, &el2);
502                 wsdlOut->next(id0, &el0);
503                 cout << *it << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
504             }
505         }
506     }
507 
testSrsFunctions()508     void testSrsFunctions()
509     {
510         cout << endl;
511         cout << "string f(string) functions" << endl;
512         cout << "---------------------------" << endl;
513 
514         FunctionOperation* fop = FunctionOperation::instance();
515 
516         list<string> functionsToTest;
517         functionsToTest.push_back("upper");
518         functionsToTest.push_back("asciistr");
519         functionsToTest.push_back("trim");
520         functionsToTest.push_back("ltrim");
521         functionsToTest.push_back("rtrim");
522 
523         // type vector is the same for drdd functions
524         vector<FunctionDataList::FuncDataListType> types;
525         types.push_back(FunctionDataList::STRING_LISTTYPE);
526         types.push_back(FunctionDataList::STRING_LISTTYPE);
527 
528         int numRows = 2;
529         StringElementType el0, el1, el2;
530         list<string>::iterator it;
531 
532         for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
533         {
534             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
535             CPPUNIT_ASSERT(fp);
536             WSDL<StringElementType>* wsdlOut = new WSDL<StringElementType>(1, numRows, fRm);
537             WSDL<StringElementType>* wsdlIn1 = new WSDL<StringElementType>(2, numRows, fRm);
538 
539             char abc[][10] = {"  abc  ", "second"};
540             abc[0][3] = 222; // 0xDE
541 
542             for (int i = 0; i < numRows; i++)
543             {
544                 el1.first = i;
545                 el1.second = abc[i];
546                 wsdlIn1->insert(el1);
547             }
548 
549             wsdlIn1->endOfInput();
550 
551             FunctionDataListSPtr listOut(new FunctionDataList());
552             FunctionDataListSPtr listIn1(new FunctionDataList());
553             FDLVec parms;
554             listOut->stringDl(wsdlOut);
555             listIn1->stringDl(wsdlIn1);
556             parms.push_back(listOut);
557             parms.push_back(listIn1);
558             fop->executeFunction(fop, fp, parms);
559             wsdlOut->endOfInput();
560 
561             int id0 = wsdlOut->getIterator();
562             int id1 = wsdlIn1->getIterator();
563 
564             for (int i = 0; i < numRows; i++)
565             {
566                 wsdlIn1->next(id1, &el1);
567                 wsdlOut->next(id0, &el0);
568                 cout << *it << "(\'" << el1.second << "\')=" << "\'" << el0.second << "\'" << endl;
569             }
570         }
571     }
572 
testAddFunctions()573     void testAddFunctions()
574     {
575         cout << endl;
576         cout << "add(<S>, <T>) functions" << endl;
577         cout << "---------------------------" << endl;
578 
579         FunctionOperation* fop = FunctionOperation::instance();
580 
581         // the map only have one entry for add_ddd, which is mapped to add(any)
582         vector<FunctionDataList::FuncDataListType> types;
583         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
584         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
585         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
586 
587         int numRows = 1;
588 
589         // double list
590         WSDL<DoubleElementType>* wsdlInD1 = new WSDL<DoubleElementType>(20, numRows, fRm);
591         WSDL<DoubleElementType>* wsdlInD2 = new WSDL<DoubleElementType>(20, numRows, fRm);
592         // uint32_t list
593         WSDL<ElementType>* wsdlInU1 = new WSDL<ElementType>(20, numRows, fRm);
594         WSDL<ElementType>* wsdlInU2 = new WSDL<ElementType>(20, numRows, fRm);
595         // string list
596         WSDL<StringElementType>* wsdlInS1 = new WSDL<StringElementType>(20, numRows, fRm);
597         WSDL<StringElementType>* wsdlInS2 = new WSDL<StringElementType>(20, numRows, fRm);
598         DoubleElementType eld;
599         ElementType       elu;
600         StringElementType els;
601 
602         for (int i = 0; i < numRows; i++)
603         {
604             eld.first = i;
605             eld.second = (0.5);
606             wsdlInD1->insert(eld);
607             wsdlInD2->insert(eld);
608             elu.first = i;
609             elu.second = (6);
610             wsdlInU1->insert(elu);
611             wsdlInU2->insert(elu);
612             els.first = i;
613             els.second = "8.8";
614             wsdlInS1->insert(els);
615             wsdlInS2->insert(els);
616         }
617 
618         wsdlInD1->endOfInput();
619         wsdlInD2->endOfInput();
620         wsdlInU1->endOfInput();
621         wsdlInU2->endOfInput();
622         wsdlInS1->endOfInput();
623         wsdlInS2->endOfInput();
624 
625         // double add(double, double)
626         {
627             DoubleElementType el0, el1, el2;
628             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
629             CPPUNIT_ASSERT(fp);
630             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
631 
632             FunctionDataListSPtr listOut(new FunctionDataList());
633             FunctionDataListSPtr listIn1(new FunctionDataList());
634             FunctionDataListSPtr listIn2(new FunctionDataList());
635             FDLVec parms;
636             listOut->doubleDl(wsdlOut);
637             listIn1->doubleDl(wsdlInD1);
638             listIn2->doubleDl(wsdlInD2);
639             parms.push_back(listOut);
640             parms.push_back(listIn1);
641             parms.push_back(listIn2);
642             fop->executeFunction(fop, fp, parms);
643             wsdlOut->endOfInput();
644 
645             int id0 = wsdlOut->getIterator();
646             int id1 = wsdlInD1->getIterator();
647             int id2 = wsdlInD2->getIterator();
648 
649             for (int i = 0; i < numRows; i++)
650             {
651                 wsdlInD1->next(id1, &el1);
652                 wsdlInD2->next(id2, &el2);
653                 wsdlOut->next(id0, &el0);
654                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
655             }
656         }
657 
658         // double add(double, uint32_t)
659         {
660             DoubleElementType el0, el1;
661             ElementType       el2;
662             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
663             CPPUNIT_ASSERT(fp);
664             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
665 
666             FunctionDataListSPtr listOut(new FunctionDataList());
667             FunctionDataListSPtr listIn1(new FunctionDataList());
668             FunctionDataListSPtr listIn2(new FunctionDataList());
669             FDLVec parms;
670             listOut->doubleDl(wsdlOut);
671             listIn1->doubleDl(wsdlInD1);
672             listIn2->uint64Dl(wsdlInU2);
673             parms.push_back(listOut);
674             parms.push_back(listIn1);
675             parms.push_back(listIn2);
676             fop->executeFunction(fop, fp, parms);
677             wsdlOut->endOfInput();
678 
679             int id0 = wsdlOut->getIterator();
680             int id1 = wsdlInD1->getIterator();
681             int id2 = wsdlInU2->getIterator();
682 
683             for (int i = 0; i < numRows; i++)
684             {
685                 wsdlInD1->next(id1, &el1);
686                 wsdlInU2->next(id2, &el2);
687                 wsdlOut->next(id0, &el0);
688                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
689             }
690         }
691 
692         // double add(double, string)
693         {
694             DoubleElementType el0, el1;
695             StringElementType el2;
696             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
697             CPPUNIT_ASSERT(fp);
698             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
699 
700             FunctionDataListSPtr listOut(new FunctionDataList());
701             FunctionDataListSPtr listIn1(new FunctionDataList());
702             FunctionDataListSPtr listIn2(new FunctionDataList());
703             FDLVec parms;
704             listOut->doubleDl(wsdlOut);
705             listIn1->doubleDl(wsdlInD1);
706             listIn2->stringDl(wsdlInS2);
707             parms.push_back(listOut);
708             parms.push_back(listIn1);
709             parms.push_back(listIn2);
710             fop->executeFunction(fop, fp, parms);
711             wsdlOut->endOfInput();
712 
713             int id0 = wsdlOut->getIterator();
714             int id1 = wsdlInD1->getIterator();
715             int id2 = wsdlInS2->getIterator();
716 
717             for (int i = 0; i < numRows; i++)
718             {
719                 wsdlInD1->next(id1, &el1);
720                 wsdlInS2->next(id2, &el2);
721                 wsdlOut->next(id0, &el0);
722                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
723             }
724         }
725 
726         // double add(uint32_t, double)
727         {
728             DoubleElementType el0, el2;
729             ElementType       el1;
730             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
731             CPPUNIT_ASSERT(fp);
732             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
733 
734             FunctionDataListSPtr listOut(new FunctionDataList());
735             FunctionDataListSPtr listIn1(new FunctionDataList());
736             FunctionDataListSPtr listIn2(new FunctionDataList());
737             FDLVec parms;
738             listOut->doubleDl(wsdlOut);
739             listIn1->uint64Dl(wsdlInU1);
740             listIn2->doubleDl(wsdlInD2);
741             parms.push_back(listOut);
742             parms.push_back(listIn1);
743             parms.push_back(listIn2);
744             fop->executeFunction(fop, fp, parms);
745             wsdlOut->endOfInput();
746 
747             int id0 = wsdlOut->getIterator();
748             int id1 = wsdlInU1->getIterator();
749             int id2 = wsdlInD2->getIterator();
750 
751             for (int i = 0; i < numRows; i++)
752             {
753                 wsdlInU1->next(id1, &el1);
754                 wsdlInD2->next(id2, &el2);
755                 wsdlOut->next(id0, &el0);
756                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
757             }
758         }
759 
760         // double add(uint32_t, uint32_t)
761         {
762             DoubleElementType el0;
763             ElementType       el1, el2;
764             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
765             CPPUNIT_ASSERT(fp);
766             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
767 
768             FunctionDataListSPtr listOut(new FunctionDataList());
769             FunctionDataListSPtr listIn1(new FunctionDataList());
770             FunctionDataListSPtr listIn2(new FunctionDataList());
771             FDLVec parms;
772             listOut->doubleDl(wsdlOut);
773             listIn1->uint64Dl(wsdlInU1);
774             listIn2->uint64Dl(wsdlInU2);
775             parms.push_back(listOut);
776             parms.push_back(listIn1);
777             parms.push_back(listIn2);
778             fop->executeFunction(fop, fp, parms);
779             wsdlOut->endOfInput();
780 
781             int id0 = wsdlOut->getIterator();
782             int id1 = wsdlInU1->getIterator();
783             int id2 = wsdlInU2->getIterator();
784 
785             for (int i = 0; i < numRows; i++)
786             {
787                 wsdlInU1->next(id1, &el1);
788                 wsdlInU2->next(id2, &el2);
789                 wsdlOut->next(id0, &el0);
790                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
791             }
792         }
793 
794         // double add(uint32_t, string)
795         {
796             DoubleElementType el0;
797             ElementType       el1;
798             StringElementType el2;
799             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
800             CPPUNIT_ASSERT(fp);
801             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
802 
803             FunctionDataListSPtr listOut(new FunctionDataList());
804             FunctionDataListSPtr listIn1(new FunctionDataList());
805             FunctionDataListSPtr listIn2(new FunctionDataList());
806             FDLVec parms;
807             listOut->doubleDl(wsdlOut);
808             listIn1->uint64Dl(wsdlInU1);
809             listIn2->stringDl(wsdlInS2);
810             parms.push_back(listOut);
811             parms.push_back(listIn1);
812             parms.push_back(listIn2);
813             fop->executeFunction(fop, fp, parms);
814             wsdlOut->endOfInput();
815 
816             int id0 = wsdlOut->getIterator();
817             int id1 = wsdlInU1->getIterator();
818             int id2 = wsdlInS2->getIterator();
819 
820             for (int i = 0; i < numRows; i++)
821             {
822                 wsdlInU1->next(id1, &el1);
823                 wsdlInS2->next(id2, &el2);
824                 wsdlOut->next(id0, &el0);
825                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
826             }
827         }
828 
829         // double add(string, double)
830         {
831             DoubleElementType el0, el2;
832             StringElementType el1;
833             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
834             CPPUNIT_ASSERT(fp);
835             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
836 
837             FunctionDataListSPtr listOut(new FunctionDataList());
838             FunctionDataListSPtr listIn1(new FunctionDataList());
839             FunctionDataListSPtr listIn2(new FunctionDataList());
840             FDLVec parms;
841             listOut->doubleDl(wsdlOut);
842             listIn1->stringDl(wsdlInS1);
843             listIn2->doubleDl(wsdlInD2);
844             parms.push_back(listOut);
845             parms.push_back(listIn1);
846             parms.push_back(listIn2);
847             fop->executeFunction(fop, fp, parms);
848             wsdlOut->endOfInput();
849 
850             int id0 = wsdlOut->getIterator();
851             int id1 = wsdlInS1->getIterator();
852             int id2 = wsdlInD2->getIterator();
853 
854             for (int i = 0; i < numRows; i++)
855             {
856                 wsdlInS1->next(id1, &el1);
857                 wsdlInD2->next(id2, &el2);
858                 wsdlOut->next(id0, &el0);
859                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
860             }
861         }
862 
863         // double add(string, uint32_t)
864         {
865             DoubleElementType el0;
866             StringElementType el1;
867             ElementType       el2;
868             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
869             CPPUNIT_ASSERT(fp);
870             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
871 
872             FunctionDataListSPtr listOut(new FunctionDataList());
873             FunctionDataListSPtr listIn1(new FunctionDataList());
874             FunctionDataListSPtr listIn2(new FunctionDataList());
875             FDLVec parms;
876             listOut->doubleDl(wsdlOut);
877             listIn1->stringDl(wsdlInS1);
878             listIn2->uint64Dl(wsdlInU2);
879             parms.push_back(listOut);
880             parms.push_back(listIn1);
881             parms.push_back(listIn2);
882             fop->executeFunction(fop, fp, parms);
883             wsdlOut->endOfInput();
884 
885             int id0 = wsdlOut->getIterator();
886             int id1 = wsdlInS1->getIterator();
887             int id2 = wsdlInU2->getIterator();
888 
889             for (int i = 0; i < numRows; i++)
890             {
891                 wsdlInS1->next(id1, &el1);
892                 wsdlInU2->next(id2, &el2);
893                 wsdlOut->next(id0, &el0);
894                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
895             }
896         }
897 
898         // double add(string, string)
899         {
900             DoubleElementType el0;
901             StringElementType el1, el2;
902             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
903             CPPUNIT_ASSERT(fp);
904             WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
905 
906             FunctionDataListSPtr listOut(new FunctionDataList());
907             FunctionDataListSPtr listIn1(new FunctionDataList());
908             FunctionDataListSPtr listIn2(new FunctionDataList());
909             FDLVec parms;
910             listOut->doubleDl(wsdlOut);
911             listIn1->stringDl(wsdlInS1);
912             listIn2->stringDl(wsdlInS2);
913             parms.push_back(listOut);
914             parms.push_back(listIn1);
915             parms.push_back(listIn2);
916             fop->executeFunction(fop, fp, parms);
917             wsdlOut->endOfInput();
918 
919             int id0 = wsdlOut->getIterator();
920             int id1 = wsdlInS1->getIterator();
921             int id2 = wsdlInS2->getIterator();
922 
923             for (int i = 0; i < numRows; i++)
924             {
925                 wsdlInS1->next(id1, &el1);
926                 wsdlInS2->next(id2, &el2);
927                 wsdlOut->next(id0, &el0);
928                 cout << "+" << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
929             }
930         }
931     }
932 
933     struct dateTime
934     {
935         unsigned msecond : 20;
936         unsigned second  : 6;
937         unsigned minute  : 6;
938         unsigned hour    : 6;
939         unsigned day     : 6;
940         unsigned month   : 4;
941         unsigned year    : 16;
942 
dateTimefunctionDriver::dateTime943         dateTime(int y = 0xFFFF, int mn = 0xF, int d = 0x3F, int h = 0x3F, int mi = 0x3F, int s = 0x3F, int ms = 0xFFFFE)
944         {
945             year = y;
946             month = mn;
947             day = d;
948             hour = h;
949             minute = mi;
950             second = s;
951             msecond = ms;
952         }
953     };
954 
testDateFunctions()955     void testDateFunctions()
956     {
957         cout << endl;
958         cout << "to_date function with formats" << endl;
959         cout << "-----------------------------" << endl;
960 
961         FunctionOperation* fop = FunctionOperation::instance();
962 
963         vector<FunctionDataList::FuncDataListType> types;
964         types.push_back(FunctionDataList::STRING_LISTTYPE);
965         types.push_back(FunctionDataList::UINT64_LISTTYPE);
966         types.push_back(FunctionDataList::STRING_CONST_LISTTYPE);
967 
968         // data list
969         AnyDataListSPtr spdl1(new AnyDataList());
970         BandedDataList* dl1 = new BandedDataList(20, fRm);
971         spdl1->bandedDL(dl1);
972 
973         dateTime dt(2007, 11, 12, 16, 7, 8, 999);
974         uint64_t idt = *(reinterpret_cast<uint64_t*>(&dt));
975         ElementType elu(0, idt);
976 
977         int numRows = 1;
978 
979         for (int i = 0; i < numRows; i++)
980         {
981             elu.first = i;
982             dl1->insert(elu);
983         }
984 
985         dl1->endOfInput();
986 
987         char fmt[6][30] = {	"YYYYMMDDHH", "YYYYMMDDHHMISS", "YYYYMMDDHHMISSFF",
988                             "YYYY-MM-DD HH:MI:SS", "MON DD, RRRR",
989                             "MM/DD/YY HH24:MI:SS.FF"
990                           };
991 
992         for (int i = 0; i < 6; i++)
993         {
994             AnyDataListSPtr spdl2(new AnyDataList());
995             StringElementType els(0, fmt[i]);
996             ConstantDataList<StringElementType>* dl2 = new ConstantDataList<StringElementType>(els);
997             spdl2->stringConstantDL(dl2);
998             dl2->endOfInput();
999 
1000             JobStepAssociation inJs;
1001             inJs.outAdd(spdl1);
1002             inJs.outAdd(spdl2);
1003 //			jobstep->outputAssociation(outJs);  // output of a job step
1004 
1005             AnyDataListSPtr spdlOut(new AnyDataList());
1006             StringDataList* dlOut = new StringDataList(1, fRm);
1007             spdlOut->strDataList(dlOut);
1008             JobStepAssociation outJs;
1009             outJs.outAdd(spdlOut);
1010 //			funJobstep->inputAssociation(inJs);
1011 //			funJobstep->outputAssociation(outJs);
1012 
1013             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("to_char", types);
1014             CPPUNIT_ASSERT(fp);
1015 
1016             FunctionDataListSPtr listOut(new FunctionDataList());
1017             FunctionDataListSPtr listIn1(new FunctionDataList());
1018             FunctionDataListSPtr listIn2(new FunctionDataList());
1019             FDLVec parms;
1020             listOut->stringDl(outJs.outAt(0)->stringDataList());
1021             listIn1->uint64Dl(inJs.outAt(0)->dataList());
1022             listIn2->stringDl(inJs.outAt(1)->stringDataList());
1023             parms.push_back(listOut);
1024             parms.push_back(listIn1);
1025             parms.push_back(listIn2);
1026             fop->executeFunction(fop, fp, parms);
1027             dlOut->endOfInput();
1028 
1029             int id0 = dlOut->getIterator();
1030             int id1 = dl1->getIterator();
1031             int id2 = dl2->getIterator();
1032             StringElementType el0;
1033             ElementType       el1;
1034             StringElementType el2;
1035 
1036             for (int i = 0; i < numRows; i++)
1037             {
1038                 dl1->next(id1, &el1);
1039                 dl2->next(id2, &el2);
1040                 dlOut->next(id0, &el0);
1041                 cout << "to_char" << "(" << el1.second << ", \'" << el2.second << "\')=" << el0.second << endl;
1042             }
1043         }
1044 
1045         // default format
1046         {
1047             JobStepAssociation inJs;
1048             inJs.outAdd(spdl1);
1049 //			jobstep->outputAssociation(outJs);  // output of a job step
1050 
1051             AnyDataListSPtr spdlOut(new AnyDataList());
1052             StringDataList* dlOut = new StringDataList(1, fRm);
1053             spdlOut->strDataList(dlOut);
1054             JobStepAssociation outJs;
1055             outJs.outAdd(spdlOut);
1056 //			funJobstep->inputAssociation(inJs);
1057 //			funJobstep->outputAssociation(outJs);
1058 
1059             FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("to_char", types);
1060             CPPUNIT_ASSERT(fp);
1061 
1062             FunctionDataListSPtr listOut(new FunctionDataList());
1063             FunctionDataListSPtr listIn1(new FunctionDataList());
1064             FDLVec parms;
1065             listOut->stringDl(outJs.outAt(0)->stringDataList());
1066             listIn1->uint64Dl(inJs.outAt(0)->dataList());
1067             parms.push_back(listOut);
1068             parms.push_back(listIn1);
1069             fop->executeFunction(fop, fp, parms);
1070             dlOut->endOfInput();
1071 
1072             int id0 = dlOut->getIterator();
1073             int id1 = dl1->getIterator();
1074             StringElementType el0;
1075             ElementType       el1;
1076 
1077             for (int i = 0; i < numRows; i++)
1078             {
1079                 dl1->next(id1, &el1);
1080                 dlOut->next(id0, &el0);
1081                 cout << "to_char" << "(" << el1.second << ")=" << el0.second << endl;
1082             }
1083         }
1084 
1085     }
1086 
testToNumFunctions()1087     void testToNumFunctions()
1088     {
1089         cout << endl;
1090         cout << "to_num function, format ignored" << endl;
1091         cout << "-------------------------------" << endl;
1092 
1093         FunctionOperation* fop = FunctionOperation::instance();
1094 
1095         vector<FunctionDataList::FuncDataListType> types;
1096         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
1097         types.push_back(FunctionDataList::STRING_LISTTYPE);
1098         types.push_back(FunctionDataList::STRING_CONST_LISTTYPE);
1099 
1100         AnyDataListSPtr spdl1(new AnyDataList());
1101         StringFifoDataList* dl1 = new StringFifoDataList(2, 100);
1102         spdl1->stringDL(dl1);
1103 
1104         const int numRows = 6;
1105         char num[numRows][30] = {	"2007111218", "1234567.8", "-123456.78",
1106                                     "2,007,111,218", "1.23E3", "-1.23E-3"
1107                                 };
1108 
1109         StringRowGroup rows;
1110 
1111         for (int i = 0; i < numRows; i++)
1112         {
1113             StringElementType els(0, num[i]);
1114             rows.et[rows.count++] = els;
1115             //			dl1->insert(els);
1116         }
1117 
1118         dl1->insert(rows);
1119         dl1->endOfInput();
1120 
1121         // format model, ignored
1122         AnyDataListSPtr spdl2(new AnyDataList());
1123         StringElementType els(0, "dummy");
1124         ConstantDataList<StringElementType>* dl2 = new ConstantDataList<StringElementType>(els);
1125         spdl2->stringConstantDL(dl2);
1126         dl2->endOfInput();
1127 
1128         JobStepAssociation inJs;
1129         inJs.outAdd(spdl1);
1130         inJs.outAdd(spdl2);
1131 //			jobstep->outputAssociation(outJs);  // output of a job step
1132 
1133         AnyDataListSPtr spdlOut(new AnyDataList());
1134         FIFO<DoubleElementType>* dlOut = new FIFO<DoubleElementType>(1, 100);
1135         spdlOut->doubleDL(dlOut);
1136         JobStepAssociation outJs;
1137         outJs.outAdd(spdlOut);
1138 //			funJobstep->inputAssociation(inJs);
1139 //			funJobstep->outputAssociation(outJs);
1140 
1141         FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("to_number", types);
1142         CPPUNIT_ASSERT(fp);
1143 
1144         FunctionDataListSPtr listOut(new FunctionDataList());
1145         FunctionDataListSPtr listIn1(new FunctionDataList());
1146         FunctionDataListSPtr listIn2(new FunctionDataList());
1147         FDLVec parms;
1148         listOut->doubleDl(outJs.outAt(0)->doubleDL());
1149         listIn1->stringDl(inJs.outAt(0)->stringDataList());
1150         listIn2->stringDl(inJs.outAt(1)->stringDataList());
1151         parms.push_back(listOut);
1152         parms.push_back(listIn1);
1153         parms.push_back(listIn2);
1154         fop->executeFunction(fop, fp, parms);
1155         dlOut->endOfInput();
1156 
1157         int id1 = dl1->getIterator();
1158         int id2 = dl2->getIterator();
1159         int id0 = dlOut->getIterator();
1160 // 		StringElementType el1;
1161         StringRowGroup el1;
1162         StringElementType el2;
1163         DoubleElementType el0;
1164 
1165         for (int i = 0; i < numRows; i++)
1166         {
1167             dl1->next(id1, &el1);
1168             dl2->next(id2, &el2);
1169             dlOut->next(id0, &el0);
1170             cout << "to_number" << "(\'" << el1.et[i].second << "\', \'" << el2.second << "\')=" << setw(20) << setprecision(10) << el0.second << endl;
1171         }
1172 
1173     }
1174 
1175     /*
1176     	void testDrdFunctions()
1177     	{
1178     		cout << endl;
1179     		cout << "double f(double) functions" << endl;
1180     		cout << "---------------------------" << endl;
1181     		FunctionOperation fo;
1182     		drdMap_t::iterator it;
1183     		drdMap_t map = fo.getDrdMap();
1184     		int numRows = 1;
1185     		DoubleElementType el, el2;
1186     		for(it = map.begin(); it!= map.end(); it++)
1187     		{
1188     			CPPUNIT_ASSERT(fo.isDrdFunction(it->first));
1189     			WSDL<DoubleElementType> wsdlIn(2, numRows);
1190     			WSDL<DoubleElementType> wsdlOut(1, numRows);
1191     			for(int i = 0; i < numRows; i++) {
1192     				el.first = i;
1193     				el.second = (0.5);
1194     				wsdlIn.insert(el);
1195     			}
1196     			wsdlIn.endOfInput();
1197     			fo.executeDrdFunction(it->first, wsdlIn, wsdlOut);
1198     			wsdlOut.endOfInput();
1199     			int id = wsdlIn.getIterator();
1200     			int id2 = wsdlOut.getIterator();
1201     			for(int i = 0; i < numRows; i++) {
1202     				wsdlIn.next(id, &el);
1203     				wsdlOut.next(id2, &el2);
1204     				cout << it->first << "(" << el.second << ")=" << el2.second << endl;
1205     			}
1206     		}
1207 
1208 
1209     	}
1210 
1211     	void testDrddFunctions()
1212     	{
1213     		cout << endl;
1214     		cout << "double f(double, double) functions" << endl;
1215     		cout << "---------------------------" << endl;
1216     		FunctionOperation fo;
1217     		drddMap_t::iterator it;
1218     		drddMap_t map = fo.getDrddMap();
1219     		int numRows = 1;
1220     		DoubleElementType el, el2, el3;
1221     		for(it = map.begin(); it!= map.end(); it++)
1222     		{
1223     			CPPUNIT_ASSERT(fo.isDrddFunction(it->first));
1224     			WSDL<DoubleElementType> wsdlIn(2, numRows);
1225     			WSDL<DoubleElementType> wsdlIn2(2, numRows);
1226     			WSDL<DoubleElementType> wsdlOut(1, numRows);
1227     			for(int i = 0; i < numRows; i++) {
1228     				el.first = i;
1229     				el.second = (0.5);
1230     				wsdlIn.insert(el);
1231     				wsdlIn2.insert(el);
1232     			}
1233     			wsdlIn.endOfInput();
1234     			wsdlIn2.endOfInput();
1235     			fo.executeDrddFunction(it->first, wsdlIn, wsdlIn2, wsdlOut);
1236     			wsdlOut.endOfInput();
1237     			int id = wsdlIn.getIterator();
1238     			int id2 = wsdlIn2.getIterator();
1239     			int id3 = wsdlOut.getIterator();
1240     			for(int i = 0; i < numRows; i++) {
1241     				wsdlIn.next(id, &el);
1242     				wsdlIn2.next(id2, &el2);
1243     				wsdlOut.next(id3, &el3);
1244     				cout << it->first << "(" << el.second << ", " << el2.second << ")=" << el3.second << endl;
1245     			}
1246     		}
1247 
1248     	}
1249 
1250     	void testSrssFunctions()
1251     	{
1252     		cout << endl;
1253     		cout << "string f(string, string) functions" << endl;
1254     		cout << "---------------------------" << endl;
1255     		FunctionOperation fo;
1256     		srssMap_t::iterator it;
1257     		srssMap_t map = fo.getSrssMap();
1258     		int numRows = 1;
1259     		StringElementType el, el2, el3;
1260     		for(it = map.begin(); it!= map.end(); it++)
1261     		{
1262     			CPPUNIT_ASSERT(fo.isSrssFunction(it->first));
1263     			WSDL<StringElementType> wsdlIn(2, numRows);
1264     			WSDL<StringElementType> wsdlIn2(2, numRows);
1265     			WSDL<StringElementType> wsdlOut(1, numRows);
1266     			for(int i = 0; i < numRows; i++) {
1267     				el.first = i;
1268     				el.second = "abc";
1269     				wsdlIn.insert(el);
1270     				wsdlIn2.insert(el);
1271     			}
1272     			wsdlIn.endOfInput();
1273     			wsdlIn2.endOfInput();
1274     			fo.executeSrssFunction(it->first, wsdlIn, wsdlIn2, wsdlOut);
1275     			wsdlOut.endOfInput();
1276     			int id = wsdlIn.getIterator();
1277     			int id2 = wsdlIn2.getIterator();
1278     			int id3 = wsdlOut.getIterator();
1279     			for(int i = 0; i < numRows; i++) {
1280     				wsdlIn.next(id, &el);
1281     				wsdlIn2.next(id2, &el2);
1282     				wsdlOut.next(id3, &el3);
1283     				cout << it->first << "(" << el.second << ", " << el2.second << ")=" << el3.second << endl;
1284     			}
1285     		}
1286 
1287     	}
1288 
1289        void testSrsFunctions()
1290         {
1291             cout << endl;
1292             cout << "string f(string) functions" << endl;
1293             cout << "---------------------------" << endl;
1294             FunctionOperation fo;
1295             srsMap_t::iterator it;
1296             srsMap_t map = fo.getSrsMap();
1297             int numRows = 2;
1298             StringElementType elIn, elOut;
1299             for(it = map.begin(); it!= map.end(); it++)
1300             {
1301                 CPPUNIT_ASSERT(fo.isSrsFunction(it->first));
1302                 WSDL<StringElementType> wsdlIn(2, numRows);
1303                 WSDL<StringElementType> wsdlOut(1, numRows);
1304     			char abc[][10] = {"  abc  ", "second"};
1305                 abc[0][3] = 222; // 0xDE
1306                 for(int i = 0; i < numRows; i++) {
1307                     elIn.first = i;
1308                     elIn.second = abc[i];
1309                     wsdlIn.insert(elIn);
1310                 }
1311                 wsdlIn.endOfInput();
1312                 fo.executeSrsFunction(it->first, wsdlIn, wsdlOut);
1313                 wsdlOut.endOfInput();
1314                 int idi = wsdlIn.getIterator();
1315                 int ido = wsdlOut.getIterator();
1316                 for(int i = 0; i < numRows; i++) {
1317                     wsdlIn.next(idi, &elIn);
1318                     wsdlOut.next(ido, &elOut);
1319                     cout << it->first << "(\"" << elIn.second << "\")=" << "\"" << elOut.second << "\"" << endl;
1320                 }
1321             }
1322 
1323         }
1324     */
1325 
1326 public:
1327 
FUNCTION_TEST()1328     void FUNCTION_TEST()
1329     {
1330         testDrdFunctions();
1331         testDrddFunctions();
1332         testSrssFunctions();
1333         testSrsFunctions();
1334         testAddFunctions();
1335         testDateFunctions();
1336         testToNumFunctions();
1337     }
1338 
1339     // Executes an addition (+ function) between two large DataLists and displays timing results.
1340     // Asserts that the output DataList contains the correct results.
PERFORMANCE_TEST()1341     void PERFORMANCE_TEST()
1342     {
1343         cout << endl << endl;
1344         cout << "Performance Test" << endl;
1345         cout << "----------------------------------------------------------------------------------------" << endl;
1346         Timer timer;
1347         int numRows = 1000 * 1000 * 2;
1348         typedef WSDL<DoubleElementType> DoubleWSDL;
1349         DoubleWSDL* wsdlOut = new DoubleWSDL(1, numRows, fRm);
1350         DoubleWSDL* wsdlIn1 = new DoubleWSDL(2, numRows, fRm);
1351         DoubleWSDL* wsdlIn2 = new DoubleWSDL(2, numRows, fRm);
1352 
1353         stringstream ss;
1354         ss << "Loading " << numRows << " DoubleElementTypes into a WSDL.";
1355         string message = ss.str();
1356         timer.start(message);
1357 
1358         DoubleElementType el;
1359 
1360         for (int i = 0; i < numRows; i++)
1361         {
1362             el.first = i;
1363             el.second = (i % 5);
1364             wsdlIn1->insert(el);
1365         }
1366 
1367         wsdlIn1->endOfInput();
1368         timer.stop(message);
1369 
1370         stringstream ss2;
1371         ss2 << "Loading " << numRows << " DoubleElementTypes into a second WSDL.";
1372         message = ss2.str();
1373         timer.start(message);
1374 
1375         for (int i = 0; i < numRows; i++)
1376         {
1377             el.first = i;
1378             el.second = (i % 5);
1379             wsdlIn2->insert(el);
1380         }
1381 
1382         wsdlIn2->endOfInput();
1383         timer.stop(message);
1384 
1385         message = "Building FunctionDataList and vector";
1386         timer.start(message);
1387         FunctionDataListSPtr listOut(new FunctionDataList());
1388         FunctionDataListSPtr listIn1(new FunctionDataList());
1389         FunctionDataListSPtr listIn2(new FunctionDataList());
1390         FDLVec parms;
1391         listOut->doubleDl(wsdlOut);
1392         listIn1->doubleDl(wsdlIn1);
1393         listIn2->doubleDl(wsdlIn2);
1394         parms.push_back(listOut);
1395         parms.push_back(listIn1);
1396         parms.push_back(listIn2);
1397 
1398         vector<FunctionDataList::FuncDataListType> types;
1399         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
1400         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
1401         types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
1402         timer.stop(message);
1403 
1404         message = "Executing addition and loading result into a third WSDL.";
1405         timer.start(message);
1406         FunctionOperation* fop = FunctionOperation::instance();
1407         FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
1408         CPPUNIT_ASSERT(fp);
1409         fop->executeFunction(fop, fp, parms);
1410         timer.stop(message);
1411         wsdlOut->endOfInput();
1412 
1413         message = "Iterating over results and doing asserts.";
1414         timer.start(message);
1415         DoubleElementType el0, el1, el2;
1416         int id0 = wsdlOut->getIterator();
1417         int id1 = wsdlIn1->getIterator();
1418         int id2 = wsdlIn2->getIterator();
1419 
1420         for (int i = 0; i < numRows; i++)
1421         {
1422             wsdlOut->next(id0, &el0);
1423             wsdlIn1->next(id1, &el1);
1424             wsdlIn2->next(id2, &el2);
1425 
1426             CPPUNIT_ASSERT(el0.first == el1.first);
1427             CPPUNIT_ASSERT(el0.second == (el1.second + el2.second));
1428         }
1429 
1430         timer.stop(message);
1431     }
1432     /*
1433     	void PERFORMANCE_TEST()
1434     	{
1435     		cout << endl << endl;
1436     		cout << "Performance Test" << endl;
1437     		cout << "----------------------------------------------------------------------------------------" << endl;
1438     		Timer timer;
1439     		int id;
1440     		int numRows = 1000 * 1000 * 2;
1441     		DoubleElementType el, el2, el3;
1442     		WSDL<DoubleElementType> wsdlIn(2, numRows);
1443     		WSDL<DoubleElementType> wsdlIn2(2, numRows);
1444     		WSDL<DoubleElementType> wsdlOut(1, numRows);
1445 
1446     		stringstream ss;
1447     		ss << "Loading " << numRows << " DoubleElementTypes into a WSDL.";
1448     		string message = ss.str();
1449     		timer.start(message);
1450 
1451     		for(int i = 0; i < numRows; i++) {
1452     			el.first = i;
1453     			el.second = (i%5);
1454     			wsdlIn.insert(el);
1455     		}
1456     		wsdlIn.endOfInput();
1457     		timer.stop(message);
1458 
1459     		stringstream ss2;
1460     		ss2 << "Loading " << numRows << " DoubleElementTypes into a second WSDL.";
1461     		message = ss2.str();
1462     		timer.start(message);
1463 
1464     		for(int i = 0; i < numRows; i++) {
1465     			el.first = i;
1466     			el.second = (i%5);
1467     			wsdlIn2.insert(el);
1468     		}
1469     		wsdlIn2.endOfInput();
1470     		timer.stop(message);
1471 
1472     		message = "Executing addition and loading result into a third WSDL.";
1473     		timer.start(message);
1474     		FunctionOperation fo;
1475     		fo.executeDrddFunction("+", wsdlIn, wsdlIn2, wsdlOut);
1476     		timer.stop(message);
1477     		wsdlOut.endOfInput();
1478 
1479     		message = "Iterating over results and doing asserts.";
1480     		timer.start(message);
1481     		id = wsdlIn.getIterator();
1482     		int id2 = wsdlIn2.getIterator();
1483     		int id3 = wsdlOut.getIterator();
1484     		for(int i = 0; i < numRows; i++) {
1485     			wsdlIn.next(id, &el);
1486     			wsdlIn2.next(id2, &el2);
1487     			wsdlOut.next(id3, &el3);
1488 
1489     			CPPUNIT_ASSERT(el.first == el3.first);
1490     			CPPUNIT_ASSERT((el.second + el2.second) == el3.second);
1491 
1492     		}
1493     		timer.stop(message);
1494     	}
1495     */
1496 };
1497 
1498 CPPUNIT_TEST_SUITE_REGISTRATION(functionDriver);
1499 
1500 
main(int argc,char ** argv)1501 int main( int argc, char** argv)
1502 {
1503     CppUnit::TextUi::TestRunner runner;
1504     CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
1505     runner.addTest( registry.makeTest() );
1506     bool wasSuccessful = runner.run( "", false );
1507     return (wasSuccessful ? 0 : 1);
1508 }
1509 
1510 
1511