You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-30 07:25:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			1499 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1499 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU General Public License
 | |
|    as published by the Free Software Foundation; version 2 of
 | |
|    the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| // $Id: tdriver-function.cpp 9210 2013-01-21 14:10:42Z rdempsey $
 | |
| #include <iostream>
 | |
| #include <list>
 | |
| #include <sstream>
 | |
| #include <pthread.h>
 | |
| #include <iomanip>
 | |
| #include <cppunit/extensions/HelperMacros.h>
 | |
| #include <cppunit/extensions/TestFactoryRegistry.h>
 | |
| #include <cppunit/ui/text/TestRunner.h>
 | |
| 
 | |
| #include "wsdl.h"
 | |
| #include "constantdatalist.h"
 | |
| 
 | |
| #include "calpontsystemcatalog.h"
 | |
| using namespace execplan;
 | |
| 
 | |
| #include "functionoperation.h"
 | |
| #include <boost/any.hpp>
 | |
| #include <boost/function.hpp>
 | |
| #include "bytestream.h"
 | |
| #include <time.h>
 | |
| #include <sys/time.h>
 | |
| #include <cmath>
 | |
| #include <boost/any.hpp>
 | |
| #include <jobstep.h>
 | |
| 
 | |
| #define DEBUG
 | |
| 
 | |
| using namespace std;
 | |
| using namespace joblist;
 | |
| using namespace messageqcpp;
 | |
| 
 | |
| // void (*fp) (double, double);
 | |
| 
 | |
| // Timer class used by this tdriver to output elapsed times, etc.
 | |
| class Timer
 | |
| {
 | |
|  public:
 | |
|   void start(const string& message)
 | |
|   {
 | |
|     if (!fHeaderDisplayed)
 | |
|     {
 | |
|       header();
 | |
|       fHeaderDisplayed = true;
 | |
|     }
 | |
| 
 | |
|     gettimeofday(&fTvStart, 0);
 | |
|     cout << timestr() << "          Start " << message << endl;
 | |
|   }
 | |
| 
 | |
|   void stop(const string& message)
 | |
|   {
 | |
|     time_t now;
 | |
|     time(&now);
 | |
|     string secondsElapsed;
 | |
|     getTimeElapsed(secondsElapsed);
 | |
|     cout << timestr() << " " << secondsElapsed << " Stop  " << message << endl;
 | |
|   }
 | |
| 
 | |
|   Timer() : fHeaderDisplayed(false)
 | |
|   {
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   struct timeval fTvStart;
 | |
|   bool fHeaderDisplayed;
 | |
| 
 | |
|   double getTimeElapsed(string& seconds)
 | |
|   {
 | |
|     struct timeval tvStop;
 | |
|     gettimeofday(&tvStop, 0);
 | |
|     double secondsElapsed =
 | |
|         (tvStop.tv_sec + (tvStop.tv_usec / 1000000.0)) - (fTvStart.tv_sec + (fTvStart.tv_usec / 1000000.0));
 | |
|     ostringstream oss;
 | |
|     oss << secondsElapsed;
 | |
|     seconds = oss.str();
 | |
|     seconds.resize(8, '0');
 | |
|     return secondsElapsed;
 | |
|   }
 | |
| 
 | |
|   string timestr()
 | |
|   {
 | |
|     struct tm tm;
 | |
|     struct timeval tv;
 | |
| 
 | |
|     gettimeofday(&tv, 0);
 | |
|     localtime_r(&tv.tv_sec, &tm);
 | |
| 
 | |
|     ostringstream oss;
 | |
|     oss << setfill('0') << setw(2) << tm.tm_hour << ':' << setw(2) << tm.tm_min << ':' << setw(2) << tm.tm_sec
 | |
|         << '.' << setw(6) << tv.tv_usec;
 | |
|     return oss.str();
 | |
|   }
 | |
| 
 | |
|   void header()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "Time            Seconds  Activity" << endl;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // Timer class used by this tdriver to output elapsed times, etc.
 | |
| class MultiTimer
 | |
| {
 | |
|  public:
 | |
|   void start(const string& message);
 | |
|   void stop(const string& message);
 | |
|   void finish()
 | |
|   {
 | |
|     // Calculate the total seconds elapsed.
 | |
|     struct timeval tvStop;
 | |
|     gettimeofday(&tvStop, 0);
 | |
|     double totalSeconds =
 | |
|         (tvStop.tv_sec + (tvStop.tv_usec / 1000000.0)) - (fTvStart.tv_sec + (fTvStart.tv_usec / 1000000.0));
 | |
| 
 | |
|     cout << endl;
 | |
|     cout << "Seconds  Percentage  Calls      Description" << endl;
 | |
| 
 | |
|     // Add a last entry into the vector for total.
 | |
|     ProcessStats total;
 | |
|     total.fTotalSeconds = totalSeconds;
 | |
|     total.fProcess = "Total";
 | |
|     total.fStartCount = 1;
 | |
|     fProcessStats.push_back(total);
 | |
| 
 | |
|     for (uint32_t i = 0; i < fProcessStats.size(); i++)
 | |
|     {
 | |
|       if (i == (fProcessStats.size() - 1))
 | |
|       {
 | |
|         cout << endl;
 | |
|       }
 | |
| 
 | |
|       // Seconds.
 | |
|       string seconds;
 | |
|       ostringstream oss;
 | |
|       oss << fProcessStats[i].fTotalSeconds;
 | |
|       seconds = oss.str();
 | |
|       seconds.resize(7, '0');
 | |
|       cout << seconds << "  ";
 | |
| 
 | |
|       // Percentage.
 | |
|       string percentage;
 | |
|       ostringstream oss2;
 | |
|       oss2 << (fProcessStats[i].fTotalSeconds / totalSeconds) * 100.0;
 | |
|       percentage = oss2.str();
 | |
|       percentage.resize(5, ' ');
 | |
|       cout << percentage << "%      ";
 | |
| 
 | |
|       // Times Initiated.
 | |
|       ostringstream oss3;
 | |
|       oss3 << fProcessStats[i].fStartCount;
 | |
|       string timesInitiated = oss3.str();
 | |
|       timesInitiated.resize(10, ' ');
 | |
|       cout << timesInitiated << " ";
 | |
| 
 | |
|       // Description.
 | |
|       cout << fProcessStats[i].fProcess << endl;
 | |
|     }
 | |
|   }
 | |
|   MultiTimer() : fStarted(false){};
 | |
| 
 | |
|  private:
 | |
|   class ProcessStats
 | |
|   {
 | |
|    public:
 | |
|     string fProcess;
 | |
|     struct timeval fTvProcessStarted;
 | |
|     double fTotalSeconds;
 | |
|     long fStartCount;
 | |
|     long fStopCount;
 | |
| 
 | |
|     ProcessStats() : fProcess(""), fTotalSeconds(0.0), fStartCount(0), fStopCount(0){};
 | |
| 
 | |
|     void processStart()
 | |
|     {
 | |
|       gettimeofday(&fTvProcessStarted, 0);
 | |
|       fStartCount++;
 | |
|     }
 | |
| 
 | |
|     void processStop()
 | |
|     {
 | |
|       struct timeval tvStop;
 | |
|       gettimeofday(&tvStop, 0);
 | |
|       fStopCount++;
 | |
|       fTotalSeconds += (tvStop.tv_sec + (tvStop.tv_usec / 1000000.0)) -
 | |
|                        (fTvProcessStarted.tv_sec + (fTvProcessStarted.tv_usec / 1000000.0));
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   struct timeval fTvStart;
 | |
|   vector<ProcessStats> fProcessStats;
 | |
|   bool fStarted;
 | |
| };
 | |
| 
 | |
| void MultiTimer::stop(const string& message)
 | |
| {
 | |
|   bool found = false;
 | |
|   uint32_t idx = 0;
 | |
| 
 | |
|   for (uint32_t i = 0; i < fProcessStats.size(); i++)
 | |
|   {
 | |
|     if (fProcessStats[i].fProcess == message)
 | |
|     {
 | |
|       idx = i;
 | |
|       found = true;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!found)
 | |
|   {
 | |
|     throw std::runtime_error("MultiTimer::stop " + message + " called without calling start first.");
 | |
|   }
 | |
| 
 | |
|   fProcessStats[idx].processStop();
 | |
| }
 | |
| 
 | |
| void MultiTimer::start(const string& message)
 | |
| {
 | |
|   bool found = false;
 | |
|   uint32_t idx = 0;
 | |
|   ProcessStats processStats;
 | |
| 
 | |
|   if (!fStarted)
 | |
|   {
 | |
|     fStarted = true;
 | |
|     gettimeofday(&fTvStart, 0);
 | |
|   }
 | |
| 
 | |
|   for (uint32_t i = 0; i < fProcessStats.size(); i++)
 | |
|   {
 | |
|     if (fProcessStats[i].fProcess == message)
 | |
|     {
 | |
|       idx = i;
 | |
|       found = true;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!found)
 | |
|   {
 | |
|     fProcessStats.push_back(processStats);
 | |
|     idx = fProcessStats.size() - 1;
 | |
|   }
 | |
| 
 | |
|   fProcessStats[idx].fProcess = message;
 | |
|   fProcessStats[idx].processStart();
 | |
| }
 | |
| 
 | |
| class functionDriver : public CppUnit::TestFixture
 | |
| {
 | |
|   CPPUNIT_TEST_SUITE(functionDriver);
 | |
|   CPPUNIT_TEST(FUNCTION_TEST);
 | |
|   CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
|  private:
 | |
|   ResourceManager fRm;
 | |
| 
 | |
|   void testDrdFunctions()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "double f(double) functions" << endl;
 | |
|     cout << "---------------------------" << endl;
 | |
| 
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
| 
 | |
|     // functions to test
 | |
|     list<string> functionsToTest;
 | |
|     functionsToTest.push_back("abs");
 | |
|     functionsToTest.push_back("acos");
 | |
|     functionsToTest.push_back("asin");
 | |
|     functionsToTest.push_back("atan");
 | |
|     functionsToTest.push_back("ceil");
 | |
|     functionsToTest.push_back("cos");
 | |
|     functionsToTest.push_back("cosh");
 | |
|     functionsToTest.push_back("exp");
 | |
|     functionsToTest.push_back("floor");
 | |
|     functionsToTest.push_back("ln");
 | |
|     functionsToTest.push_back("log2");
 | |
|     functionsToTest.push_back("log10");
 | |
|     functionsToTest.push_back("sin");
 | |
|     functionsToTest.push_back("sinh");
 | |
|     functionsToTest.push_back("sqrt");
 | |
|     functionsToTest.push_back("tan");
 | |
|     functionsToTest.push_back("tanh");
 | |
| 
 | |
|     // type vector is the same for drd functions
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
| 
 | |
|     int numRows = 1;
 | |
|     DoubleElementType el0, el1;
 | |
|     list<string>::iterator it;
 | |
| 
 | |
|     for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
 | |
|     {
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
|       WSDL<DoubleElementType>* wsdlIn1 = new WSDL<DoubleElementType>(2, numRows, fRm);
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         el1.first = i;
 | |
|         el1.second = (0.5);
 | |
|         wsdlIn1->insert(el1);
 | |
|       }
 | |
| 
 | |
|       wsdlIn1->endOfInput();
 | |
| 
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->doubleDl(wsdlIn1);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlIn1->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlIn1->next(id1, &el1);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << *it << "(" << el1.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void testDrddFunctions()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "double f(double, double) functions" << endl;
 | |
|     cout << "---------------------------" << endl;
 | |
| 
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
| 
 | |
|     list<string> functionsToTest;
 | |
|     functionsToTest.push_back("atan2");
 | |
|     functionsToTest.push_back("power");
 | |
|     functionsToTest.push_back("+");
 | |
|     functionsToTest.push_back("-");
 | |
|     functionsToTest.push_back("*");
 | |
|     functionsToTest.push_back("/");
 | |
| 
 | |
|     // type vector is the same for drdd functions
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
| 
 | |
|     int numRows = 1;
 | |
|     DoubleElementType el0, el1, el2;
 | |
|     list<string>::iterator it;
 | |
| 
 | |
|     for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
 | |
|     {
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
|       WSDL<DoubleElementType>* wsdlIn1 = new WSDL<DoubleElementType>(2, numRows, fRm);
 | |
|       WSDL<DoubleElementType>* wsdlIn2 = new WSDL<DoubleElementType>(2, numRows, fRm);
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         el1.first = i;
 | |
|         el1.second = (0.5);
 | |
|         wsdlIn1->insert(el1);
 | |
|         wsdlIn2->insert(el1);  // the data in two list is the same
 | |
|       }
 | |
| 
 | |
|       wsdlIn1->endOfInput();
 | |
|       wsdlIn2->endOfInput();
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->doubleDl(wsdlIn1);
 | |
|       listIn2->doubleDl(wsdlIn2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlIn1->getIterator();
 | |
|       int id2 = wsdlIn2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlIn1->next(id1, &el1);
 | |
|         wsdlIn2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << *it << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void testSrssFunctions()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "string f(string, string) functions" << endl;
 | |
|     cout << "---------------------------" << endl;
 | |
| 
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
| 
 | |
|     list<string> functionsToTest;
 | |
|     functionsToTest.push_back("||");
 | |
|     functionsToTest.push_back("concat");
 | |
| 
 | |
|     // type vector is the same for drdd functions
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::STRING_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::STRING_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::STRING_LISTTYPE);
 | |
| 
 | |
|     int numRows = 1;
 | |
|     StringElementType el0, el1, el2;
 | |
|     list<string>::iterator it;
 | |
| 
 | |
|     for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
 | |
|     {
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<StringElementType>* wsdlOut = new WSDL<StringElementType>(1, numRows, fRm);
 | |
|       WSDL<StringElementType>* wsdlIn1 = new WSDL<StringElementType>(2, numRows, fRm);
 | |
|       WSDL<StringElementType>* wsdlIn2 = new WSDL<StringElementType>(2, numRows, fRm);
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         el1.first = i;
 | |
|         el1.second = "abc";
 | |
|         wsdlIn1->insert(el1);
 | |
|         wsdlIn2->insert(el1);  // the data in two list is the same
 | |
|       }
 | |
| 
 | |
|       wsdlIn1->endOfInput();
 | |
|       wsdlIn2->endOfInput();
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->stringDl(wsdlOut);
 | |
|       listIn1->stringDl(wsdlIn1);
 | |
|       listIn2->stringDl(wsdlIn2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlIn1->getIterator();
 | |
|       int id2 = wsdlIn2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlIn1->next(id1, &el1);
 | |
|         wsdlIn2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << *it << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void testSrsFunctions()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "string f(string) functions" << endl;
 | |
|     cout << "---------------------------" << endl;
 | |
| 
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
| 
 | |
|     list<string> functionsToTest;
 | |
|     functionsToTest.push_back("upper");
 | |
|     functionsToTest.push_back("asciistr");
 | |
|     functionsToTest.push_back("trim");
 | |
|     functionsToTest.push_back("ltrim");
 | |
|     functionsToTest.push_back("rtrim");
 | |
| 
 | |
|     // type vector is the same for drdd functions
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::STRING_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::STRING_LISTTYPE);
 | |
| 
 | |
|     int numRows = 2;
 | |
|     StringElementType el0, el1, el2;
 | |
|     list<string>::iterator it;
 | |
| 
 | |
|     for (it = functionsToTest.begin(); it != functionsToTest.end(); it++)
 | |
|     {
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr(*it, types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<StringElementType>* wsdlOut = new WSDL<StringElementType>(1, numRows, fRm);
 | |
|       WSDL<StringElementType>* wsdlIn1 = new WSDL<StringElementType>(2, numRows, fRm);
 | |
| 
 | |
|       char abc[][10] = {"  abc  ", "second"};
 | |
|       abc[0][3] = 222;  // 0xDE
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         el1.first = i;
 | |
|         el1.second = abc[i];
 | |
|         wsdlIn1->insert(el1);
 | |
|       }
 | |
| 
 | |
|       wsdlIn1->endOfInput();
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->stringDl(wsdlOut);
 | |
|       listIn1->stringDl(wsdlIn1);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlIn1->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlIn1->next(id1, &el1);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << *it << "(\'" << el1.second << "\')="
 | |
|              << "\'" << el0.second << "\'" << endl;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void testAddFunctions()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "add(<S>, <T>) functions" << endl;
 | |
|     cout << "---------------------------" << endl;
 | |
| 
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
| 
 | |
|     // the map only have one entry for add_ddd, which is mapped to add(any)
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
| 
 | |
|     int numRows = 1;
 | |
| 
 | |
|     // double list
 | |
|     WSDL<DoubleElementType>* wsdlInD1 = new WSDL<DoubleElementType>(20, numRows, fRm);
 | |
|     WSDL<DoubleElementType>* wsdlInD2 = new WSDL<DoubleElementType>(20, numRows, fRm);
 | |
|     // uint32_t list
 | |
|     WSDL<ElementType>* wsdlInU1 = new WSDL<ElementType>(20, numRows, fRm);
 | |
|     WSDL<ElementType>* wsdlInU2 = new WSDL<ElementType>(20, numRows, fRm);
 | |
|     // string list
 | |
|     WSDL<StringElementType>* wsdlInS1 = new WSDL<StringElementType>(20, numRows, fRm);
 | |
|     WSDL<StringElementType>* wsdlInS2 = new WSDL<StringElementType>(20, numRows, fRm);
 | |
|     DoubleElementType eld;
 | |
|     ElementType elu;
 | |
|     StringElementType els;
 | |
| 
 | |
|     for (int i = 0; i < numRows; i++)
 | |
|     {
 | |
|       eld.first = i;
 | |
|       eld.second = (0.5);
 | |
|       wsdlInD1->insert(eld);
 | |
|       wsdlInD2->insert(eld);
 | |
|       elu.first = i;
 | |
|       elu.second = (6);
 | |
|       wsdlInU1->insert(elu);
 | |
|       wsdlInU2->insert(elu);
 | |
|       els.first = i;
 | |
|       els.second = "8.8";
 | |
|       wsdlInS1->insert(els);
 | |
|       wsdlInS2->insert(els);
 | |
|     }
 | |
| 
 | |
|     wsdlInD1->endOfInput();
 | |
|     wsdlInD2->endOfInput();
 | |
|     wsdlInU1->endOfInput();
 | |
|     wsdlInU2->endOfInput();
 | |
|     wsdlInS1->endOfInput();
 | |
|     wsdlInS2->endOfInput();
 | |
| 
 | |
|     // double add(double, double)
 | |
|     {
 | |
|       DoubleElementType el0, el1, el2;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->doubleDl(wsdlInD1);
 | |
|       listIn2->doubleDl(wsdlInD2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInD1->getIterator();
 | |
|       int id2 = wsdlInD2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInD1->next(id1, &el1);
 | |
|         wsdlInD2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(double, uint32_t)
 | |
|     {
 | |
|       DoubleElementType el0, el1;
 | |
|       ElementType el2;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->doubleDl(wsdlInD1);
 | |
|       listIn2->uint64Dl(wsdlInU2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInD1->getIterator();
 | |
|       int id2 = wsdlInU2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInD1->next(id1, &el1);
 | |
|         wsdlInU2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(double, string)
 | |
|     {
 | |
|       DoubleElementType el0, el1;
 | |
|       StringElementType el2;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->doubleDl(wsdlInD1);
 | |
|       listIn2->stringDl(wsdlInS2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInD1->getIterator();
 | |
|       int id2 = wsdlInS2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInD1->next(id1, &el1);
 | |
|         wsdlInS2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(uint32_t, double)
 | |
|     {
 | |
|       DoubleElementType el0, el2;
 | |
|       ElementType el1;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->uint64Dl(wsdlInU1);
 | |
|       listIn2->doubleDl(wsdlInD2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInU1->getIterator();
 | |
|       int id2 = wsdlInD2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInU1->next(id1, &el1);
 | |
|         wsdlInD2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(uint32_t, uint32_t)
 | |
|     {
 | |
|       DoubleElementType el0;
 | |
|       ElementType el1, el2;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->uint64Dl(wsdlInU1);
 | |
|       listIn2->uint64Dl(wsdlInU2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInU1->getIterator();
 | |
|       int id2 = wsdlInU2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInU1->next(id1, &el1);
 | |
|         wsdlInU2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(uint32_t, string)
 | |
|     {
 | |
|       DoubleElementType el0;
 | |
|       ElementType el1;
 | |
|       StringElementType el2;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->uint64Dl(wsdlInU1);
 | |
|       listIn2->stringDl(wsdlInS2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInU1->getIterator();
 | |
|       int id2 = wsdlInS2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInU1->next(id1, &el1);
 | |
|         wsdlInS2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(string, double)
 | |
|     {
 | |
|       DoubleElementType el0, el2;
 | |
|       StringElementType el1;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->stringDl(wsdlInS1);
 | |
|       listIn2->doubleDl(wsdlInD2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInS1->getIterator();
 | |
|       int id2 = wsdlInD2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInS1->next(id1, &el1);
 | |
|         wsdlInD2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(string, uint32_t)
 | |
|     {
 | |
|       DoubleElementType el0;
 | |
|       StringElementType el1;
 | |
|       ElementType el2;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->stringDl(wsdlInS1);
 | |
|       listIn2->uint64Dl(wsdlInU2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInS1->getIterator();
 | |
|       int id2 = wsdlInU2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInS1->next(id1, &el1);
 | |
|         wsdlInU2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // double add(string, string)
 | |
|     {
 | |
|       DoubleElementType el0;
 | |
|       StringElementType el1, el2;
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
|       WSDL<DoubleElementType>* wsdlOut = new WSDL<DoubleElementType>(1, numRows, fRm);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->doubleDl(wsdlOut);
 | |
|       listIn1->stringDl(wsdlInS1);
 | |
|       listIn2->stringDl(wsdlInS2);
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       wsdlOut->endOfInput();
 | |
| 
 | |
|       int id0 = wsdlOut->getIterator();
 | |
|       int id1 = wsdlInS1->getIterator();
 | |
|       int id2 = wsdlInS2->getIterator();
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         wsdlInS1->next(id1, &el1);
 | |
|         wsdlInS2->next(id2, &el2);
 | |
|         wsdlOut->next(id0, &el0);
 | |
|         cout << "+"
 | |
|              << "(" << el1.second << ", " << el2.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   struct dateTime
 | |
|   {
 | |
|     unsigned msecond : 20;
 | |
|     unsigned second : 6;
 | |
|     unsigned minute : 6;
 | |
|     unsigned hour : 6;
 | |
|     unsigned day : 6;
 | |
|     unsigned month : 4;
 | |
|     unsigned year : 16;
 | |
| 
 | |
|     dateTime(int y = 0xFFFF, int mn = 0xF, int d = 0x3F, int h = 0x3F, int mi = 0x3F, int s = 0x3F,
 | |
|              int ms = 0xFFFFE)
 | |
|     {
 | |
|       year = y;
 | |
|       month = mn;
 | |
|       day = d;
 | |
|       hour = h;
 | |
|       minute = mi;
 | |
|       second = s;
 | |
|       msecond = ms;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   void testDateFunctions()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "to_date function with formats" << endl;
 | |
|     cout << "-----------------------------" << endl;
 | |
| 
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
| 
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::STRING_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::UINT64_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::STRING_CONST_LISTTYPE);
 | |
| 
 | |
|     // data list
 | |
|     AnyDataListSPtr spdl1(new AnyDataList());
 | |
|     BandedDataList* dl1 = new BandedDataList(20, fRm);
 | |
|     spdl1->bandedDL(dl1);
 | |
| 
 | |
|     dateTime dt(2007, 11, 12, 16, 7, 8, 999);
 | |
|     uint64_t idt = *(reinterpret_cast<uint64_t*>(&dt));
 | |
|     ElementType elu(0, idt);
 | |
| 
 | |
|     int numRows = 1;
 | |
| 
 | |
|     for (int i = 0; i < numRows; i++)
 | |
|     {
 | |
|       elu.first = i;
 | |
|       dl1->insert(elu);
 | |
|     }
 | |
| 
 | |
|     dl1->endOfInput();
 | |
| 
 | |
|     char fmt[6][30] = {"YYYYMMDDHH",          "YYYYMMDDHHMISS", "YYYYMMDDHHMISSFF",
 | |
|                        "YYYY-MM-DD HH:MI:SS", "MON DD, RRRR",   "MM/DD/YY HH24:MI:SS.FF"};
 | |
| 
 | |
|     for (int i = 0; i < 6; i++)
 | |
|     {
 | |
|       AnyDataListSPtr spdl2(new AnyDataList());
 | |
|       StringElementType els(0, fmt[i]);
 | |
|       ConstantDataList<StringElementType>* dl2 = new ConstantDataList<StringElementType>(els);
 | |
|       spdl2->stringConstantDL(dl2);
 | |
|       dl2->endOfInput();
 | |
| 
 | |
|       JobStepAssociation inJs;
 | |
|       inJs.outAdd(spdl1);
 | |
|       inJs.outAdd(spdl2);
 | |
|       //			jobstep->outputAssociation(outJs);  // output of a job step
 | |
| 
 | |
|       AnyDataListSPtr spdlOut(new AnyDataList());
 | |
|       StringDataList* dlOut = new StringDataList(1, fRm);
 | |
|       spdlOut->strDataList(dlOut);
 | |
|       JobStepAssociation outJs;
 | |
|       outJs.outAdd(spdlOut);
 | |
|       //			funJobstep->inputAssociation(inJs);
 | |
|       //			funJobstep->outputAssociation(outJs);
 | |
| 
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("to_char", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->stringDl(outJs.outAt(0)->stringDataList());
 | |
|       listIn1->uint64Dl(inJs.outAt(0)->dataList());
 | |
|       listIn2->stringDl(inJs.outAt(1)->stringDataList());
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       parms.push_back(listIn2);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       dlOut->endOfInput();
 | |
| 
 | |
|       int id0 = dlOut->getIterator();
 | |
|       int id1 = dl1->getIterator();
 | |
|       int id2 = dl2->getIterator();
 | |
|       StringElementType el0;
 | |
|       ElementType el1;
 | |
|       StringElementType el2;
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         dl1->next(id1, &el1);
 | |
|         dl2->next(id2, &el2);
 | |
|         dlOut->next(id0, &el0);
 | |
|         cout << "to_char"
 | |
|              << "(" << el1.second << ", \'" << el2.second << "\')=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // default format
 | |
|     {
 | |
|       JobStepAssociation inJs;
 | |
|       inJs.outAdd(spdl1);
 | |
|       //			jobstep->outputAssociation(outJs);  // output of a job step
 | |
| 
 | |
|       AnyDataListSPtr spdlOut(new AnyDataList());
 | |
|       StringDataList* dlOut = new StringDataList(1, fRm);
 | |
|       spdlOut->strDataList(dlOut);
 | |
|       JobStepAssociation outJs;
 | |
|       outJs.outAdd(spdlOut);
 | |
|       //			funJobstep->inputAssociation(inJs);
 | |
|       //			funJobstep->outputAssociation(outJs);
 | |
| 
 | |
|       FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("to_char", types);
 | |
|       CPPUNIT_ASSERT(fp);
 | |
| 
 | |
|       FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|       FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|       FDLVec parms;
 | |
|       listOut->stringDl(outJs.outAt(0)->stringDataList());
 | |
|       listIn1->uint64Dl(inJs.outAt(0)->dataList());
 | |
|       parms.push_back(listOut);
 | |
|       parms.push_back(listIn1);
 | |
|       fop->executeFunction(fop, fp, parms);
 | |
|       dlOut->endOfInput();
 | |
| 
 | |
|       int id0 = dlOut->getIterator();
 | |
|       int id1 = dl1->getIterator();
 | |
|       StringElementType el0;
 | |
|       ElementType el1;
 | |
| 
 | |
|       for (int i = 0; i < numRows; i++)
 | |
|       {
 | |
|         dl1->next(id1, &el1);
 | |
|         dlOut->next(id0, &el0);
 | |
|         cout << "to_char"
 | |
|              << "(" << el1.second << ")=" << el0.second << endl;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void testToNumFunctions()
 | |
|   {
 | |
|     cout << endl;
 | |
|     cout << "to_num function, format ignored" << endl;
 | |
|     cout << "-------------------------------" << endl;
 | |
| 
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
| 
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::STRING_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::STRING_CONST_LISTTYPE);
 | |
| 
 | |
|     AnyDataListSPtr spdl1(new AnyDataList());
 | |
|     StringFifoDataList* dl1 = new StringFifoDataList(2, 100);
 | |
|     spdl1->stringDL(dl1);
 | |
| 
 | |
|     const int numRows = 6;
 | |
|     char num[numRows][30] = {"2007111218", "1234567.8", "-123456.78", "2,007,111,218", "1.23E3", "-1.23E-3"};
 | |
| 
 | |
|     StringRowGroup rows;
 | |
| 
 | |
|     for (int i = 0; i < numRows; i++)
 | |
|     {
 | |
|       StringElementType els(0, num[i]);
 | |
|       rows.et[rows.count++] = els;
 | |
|       //			dl1->insert(els);
 | |
|     }
 | |
| 
 | |
|     dl1->insert(rows);
 | |
|     dl1->endOfInput();
 | |
| 
 | |
|     // format model, ignored
 | |
|     AnyDataListSPtr spdl2(new AnyDataList());
 | |
|     StringElementType els(0, "dummy");
 | |
|     ConstantDataList<StringElementType>* dl2 = new ConstantDataList<StringElementType>(els);
 | |
|     spdl2->stringConstantDL(dl2);
 | |
|     dl2->endOfInput();
 | |
| 
 | |
|     JobStepAssociation inJs;
 | |
|     inJs.outAdd(spdl1);
 | |
|     inJs.outAdd(spdl2);
 | |
|     //			jobstep->outputAssociation(outJs);  // output of a job step
 | |
| 
 | |
|     AnyDataListSPtr spdlOut(new AnyDataList());
 | |
|     FIFO<DoubleElementType>* dlOut = new FIFO<DoubleElementType>(1, 100);
 | |
|     spdlOut->doubleDL(dlOut);
 | |
|     JobStepAssociation outJs;
 | |
|     outJs.outAdd(spdlOut);
 | |
|     //			funJobstep->inputAssociation(inJs);
 | |
|     //			funJobstep->outputAssociation(outJs);
 | |
| 
 | |
|     FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("to_number", types);
 | |
|     CPPUNIT_ASSERT(fp);
 | |
| 
 | |
|     FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|     FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|     FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|     FDLVec parms;
 | |
|     listOut->doubleDl(outJs.outAt(0)->doubleDL());
 | |
|     listIn1->stringDl(inJs.outAt(0)->stringDataList());
 | |
|     listIn2->stringDl(inJs.outAt(1)->stringDataList());
 | |
|     parms.push_back(listOut);
 | |
|     parms.push_back(listIn1);
 | |
|     parms.push_back(listIn2);
 | |
|     fop->executeFunction(fop, fp, parms);
 | |
|     dlOut->endOfInput();
 | |
| 
 | |
|     int id1 = dl1->getIterator();
 | |
|     int id2 = dl2->getIterator();
 | |
|     int id0 = dlOut->getIterator();
 | |
|     // 		StringElementType el1;
 | |
|     StringRowGroup el1;
 | |
|     StringElementType el2;
 | |
|     DoubleElementType el0;
 | |
| 
 | |
|     for (int i = 0; i < numRows; i++)
 | |
|     {
 | |
|       dl1->next(id1, &el1);
 | |
|       dl2->next(id2, &el2);
 | |
|       dlOut->next(id0, &el0);
 | |
|       cout << "to_number"
 | |
|            << "(\'" << el1.et[i].second << "\', \'" << el2.second << "\')=" << setw(20) << setprecision(10)
 | |
|            << el0.second << endl;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /*
 | |
|       void testDrdFunctions()
 | |
|       {
 | |
|               cout << endl;
 | |
|               cout << "double f(double) functions" << endl;
 | |
|               cout << "---------------------------" << endl;
 | |
|               FunctionOperation fo;
 | |
|               drdMap_t::iterator it;
 | |
|               drdMap_t map = fo.getDrdMap();
 | |
|               int numRows = 1;
 | |
|               DoubleElementType el, el2;
 | |
|               for(it = map.begin(); it!= map.end(); it++)
 | |
|               {
 | |
|                       CPPUNIT_ASSERT(fo.isDrdFunction(it->first));
 | |
|                       WSDL<DoubleElementType> wsdlIn(2, numRows);
 | |
|                       WSDL<DoubleElementType> wsdlOut(1, numRows);
 | |
|                       for(int i = 0; i < numRows; i++) {
 | |
|                               el.first = i;
 | |
|                               el.second = (0.5);
 | |
|                               wsdlIn.insert(el);
 | |
|                       }
 | |
|                       wsdlIn.endOfInput();
 | |
|                       fo.executeDrdFunction(it->first, wsdlIn, wsdlOut);
 | |
|                       wsdlOut.endOfInput();
 | |
|                       int id = wsdlIn.getIterator();
 | |
|                       int id2 = wsdlOut.getIterator();
 | |
|                       for(int i = 0; i < numRows; i++) {
 | |
|                               wsdlIn.next(id, &el);
 | |
|                               wsdlOut.next(id2, &el2);
 | |
|                               cout << it->first << "(" << el.second << ")=" << el2.second << endl;
 | |
|                       }
 | |
|               }
 | |
| 
 | |
| 
 | |
|       }
 | |
| 
 | |
|       void testDrddFunctions()
 | |
|       {
 | |
|               cout << endl;
 | |
|               cout << "double f(double, double) functions" << endl;
 | |
|               cout << "---------------------------" << endl;
 | |
|               FunctionOperation fo;
 | |
|               drddMap_t::iterator it;
 | |
|               drddMap_t map = fo.getDrddMap();
 | |
|               int numRows = 1;
 | |
|               DoubleElementType el, el2, el3;
 | |
|               for(it = map.begin(); it!= map.end(); it++)
 | |
|               {
 | |
|                       CPPUNIT_ASSERT(fo.isDrddFunction(it->first));
 | |
|                       WSDL<DoubleElementType> wsdlIn(2, numRows);
 | |
|                       WSDL<DoubleElementType> wsdlIn2(2, numRows);
 | |
|                       WSDL<DoubleElementType> wsdlOut(1, numRows);
 | |
|                       for(int i = 0; i < numRows; i++) {
 | |
|                               el.first = i;
 | |
|                               el.second = (0.5);
 | |
|                               wsdlIn.insert(el);
 | |
|                               wsdlIn2.insert(el);
 | |
|                       }
 | |
|                       wsdlIn.endOfInput();
 | |
|                       wsdlIn2.endOfInput();
 | |
|                       fo.executeDrddFunction(it->first, wsdlIn, wsdlIn2, wsdlOut);
 | |
|                       wsdlOut.endOfInput();
 | |
|                       int id = wsdlIn.getIterator();
 | |
|                       int id2 = wsdlIn2.getIterator();
 | |
|                       int id3 = wsdlOut.getIterator();
 | |
|                       for(int i = 0; i < numRows; i++) {
 | |
|                               wsdlIn.next(id, &el);
 | |
|                               wsdlIn2.next(id2, &el2);
 | |
|                               wsdlOut.next(id3, &el3);
 | |
|                               cout << it->first << "(" << el.second << ", " << el2.second << ")=" <<
 | |
|      el3.second << endl;
 | |
|                       }
 | |
|               }
 | |
| 
 | |
|       }
 | |
| 
 | |
|       void testSrssFunctions()
 | |
|       {
 | |
|               cout << endl;
 | |
|               cout << "string f(string, string) functions" << endl;
 | |
|               cout << "---------------------------" << endl;
 | |
|               FunctionOperation fo;
 | |
|               srssMap_t::iterator it;
 | |
|               srssMap_t map = fo.getSrssMap();
 | |
|               int numRows = 1;
 | |
|               StringElementType el, el2, el3;
 | |
|               for(it = map.begin(); it!= map.end(); it++)
 | |
|               {
 | |
|                       CPPUNIT_ASSERT(fo.isSrssFunction(it->first));
 | |
|                       WSDL<StringElementType> wsdlIn(2, numRows);
 | |
|                       WSDL<StringElementType> wsdlIn2(2, numRows);
 | |
|                       WSDL<StringElementType> wsdlOut(1, numRows);
 | |
|                       for(int i = 0; i < numRows; i++) {
 | |
|                               el.first = i;
 | |
|                               el.second = "abc";
 | |
|                               wsdlIn.insert(el);
 | |
|                               wsdlIn2.insert(el);
 | |
|                       }
 | |
|                       wsdlIn.endOfInput();
 | |
|                       wsdlIn2.endOfInput();
 | |
|                       fo.executeSrssFunction(it->first, wsdlIn, wsdlIn2, wsdlOut);
 | |
|                       wsdlOut.endOfInput();
 | |
|                       int id = wsdlIn.getIterator();
 | |
|                       int id2 = wsdlIn2.getIterator();
 | |
|                       int id3 = wsdlOut.getIterator();
 | |
|                       for(int i = 0; i < numRows; i++) {
 | |
|                               wsdlIn.next(id, &el);
 | |
|                               wsdlIn2.next(id2, &el2);
 | |
|                               wsdlOut.next(id3, &el3);
 | |
|                               cout << it->first << "(" << el.second << ", " << el2.second << ")=" <<
 | |
|      el3.second << endl;
 | |
|                       }
 | |
|               }
 | |
| 
 | |
|       }
 | |
| 
 | |
|      void testSrsFunctions()
 | |
|       {
 | |
|           cout << endl;
 | |
|           cout << "string f(string) functions" << endl;
 | |
|           cout << "---------------------------" << endl;
 | |
|           FunctionOperation fo;
 | |
|           srsMap_t::iterator it;
 | |
|           srsMap_t map = fo.getSrsMap();
 | |
|           int numRows = 2;
 | |
|           StringElementType elIn, elOut;
 | |
|           for(it = map.begin(); it!= map.end(); it++)
 | |
|           {
 | |
|               CPPUNIT_ASSERT(fo.isSrsFunction(it->first));
 | |
|               WSDL<StringElementType> wsdlIn(2, numRows);
 | |
|               WSDL<StringElementType> wsdlOut(1, numRows);
 | |
|                       char abc[][10] = {"  abc  ", "second"};
 | |
|               abc[0][3] = 222; // 0xDE
 | |
|               for(int i = 0; i < numRows; i++) {
 | |
|                   elIn.first = i;
 | |
|                   elIn.second = abc[i];
 | |
|                   wsdlIn.insert(elIn);
 | |
|               }
 | |
|               wsdlIn.endOfInput();
 | |
|               fo.executeSrsFunction(it->first, wsdlIn, wsdlOut);
 | |
|               wsdlOut.endOfInput();
 | |
|               int idi = wsdlIn.getIterator();
 | |
|               int ido = wsdlOut.getIterator();
 | |
|               for(int i = 0; i < numRows; i++) {
 | |
|                   wsdlIn.next(idi, &elIn);
 | |
|                   wsdlOut.next(ido, &elOut);
 | |
|                   cout << it->first << "(\"" << elIn.second << "\")=" << "\"" << elOut.second << "\"" << endl;
 | |
|               }
 | |
|           }
 | |
| 
 | |
|       }
 | |
|   */
 | |
| 
 | |
|  public:
 | |
|   void FUNCTION_TEST()
 | |
|   {
 | |
|     testDrdFunctions();
 | |
|     testDrddFunctions();
 | |
|     testSrssFunctions();
 | |
|     testSrsFunctions();
 | |
|     testAddFunctions();
 | |
|     testDateFunctions();
 | |
|     testToNumFunctions();
 | |
|   }
 | |
| 
 | |
|   // Executes an addition (+ function) between two large DataLists and displays timing results.
 | |
|   // Asserts that the output DataList contains the correct results.
 | |
|   void PERFORMANCE_TEST()
 | |
|   {
 | |
|     cout << endl << endl;
 | |
|     cout << "Performance Test" << endl;
 | |
|     cout << "----------------------------------------------------------------------------------------"
 | |
|          << endl;
 | |
|     Timer timer;
 | |
|     int numRows = 1000 * 1000 * 2;
 | |
|     typedef WSDL<DoubleElementType> DoubleWSDL;
 | |
|     DoubleWSDL* wsdlOut = new DoubleWSDL(1, numRows, fRm);
 | |
|     DoubleWSDL* wsdlIn1 = new DoubleWSDL(2, numRows, fRm);
 | |
|     DoubleWSDL* wsdlIn2 = new DoubleWSDL(2, numRows, fRm);
 | |
| 
 | |
|     stringstream ss;
 | |
|     ss << "Loading " << numRows << " DoubleElementTypes into a WSDL.";
 | |
|     string message = ss.str();
 | |
|     timer.start(message);
 | |
| 
 | |
|     DoubleElementType el;
 | |
| 
 | |
|     for (int i = 0; i < numRows; i++)
 | |
|     {
 | |
|       el.first = i;
 | |
|       el.second = (i % 5);
 | |
|       wsdlIn1->insert(el);
 | |
|     }
 | |
| 
 | |
|     wsdlIn1->endOfInput();
 | |
|     timer.stop(message);
 | |
| 
 | |
|     stringstream ss2;
 | |
|     ss2 << "Loading " << numRows << " DoubleElementTypes into a second WSDL.";
 | |
|     message = ss2.str();
 | |
|     timer.start(message);
 | |
| 
 | |
|     for (int i = 0; i < numRows; i++)
 | |
|     {
 | |
|       el.first = i;
 | |
|       el.second = (i % 5);
 | |
|       wsdlIn2->insert(el);
 | |
|     }
 | |
| 
 | |
|     wsdlIn2->endOfInput();
 | |
|     timer.stop(message);
 | |
| 
 | |
|     message = "Building FunctionDataList and vector";
 | |
|     timer.start(message);
 | |
|     FunctionDataListSPtr listOut(new FunctionDataList());
 | |
|     FunctionDataListSPtr listIn1(new FunctionDataList());
 | |
|     FunctionDataListSPtr listIn2(new FunctionDataList());
 | |
|     FDLVec parms;
 | |
|     listOut->doubleDl(wsdlOut);
 | |
|     listIn1->doubleDl(wsdlIn1);
 | |
|     listIn2->doubleDl(wsdlIn2);
 | |
|     parms.push_back(listOut);
 | |
|     parms.push_back(listIn1);
 | |
|     parms.push_back(listIn2);
 | |
| 
 | |
|     vector<FunctionDataList::FuncDataListType> types;
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     types.push_back(FunctionDataList::DOUBLE_LISTTYPE);
 | |
|     timer.stop(message);
 | |
| 
 | |
|     message = "Executing addition and loading result into a third WSDL.";
 | |
|     timer.start(message);
 | |
|     FunctionOperation* fop = FunctionOperation::instance();
 | |
|     FunctionOperation::Function_t* fp = fop->getFunctionObjPtr("+", types);
 | |
|     CPPUNIT_ASSERT(fp);
 | |
|     fop->executeFunction(fop, fp, parms);
 | |
|     timer.stop(message);
 | |
|     wsdlOut->endOfInput();
 | |
| 
 | |
|     message = "Iterating over results and doing asserts.";
 | |
|     timer.start(message);
 | |
|     DoubleElementType el0, el1, el2;
 | |
|     int id0 = wsdlOut->getIterator();
 | |
|     int id1 = wsdlIn1->getIterator();
 | |
|     int id2 = wsdlIn2->getIterator();
 | |
| 
 | |
|     for (int i = 0; i < numRows; i++)
 | |
|     {
 | |
|       wsdlOut->next(id0, &el0);
 | |
|       wsdlIn1->next(id1, &el1);
 | |
|       wsdlIn2->next(id2, &el2);
 | |
| 
 | |
|       CPPUNIT_ASSERT(el0.first == el1.first);
 | |
|       CPPUNIT_ASSERT(el0.second == (el1.second + el2.second));
 | |
|     }
 | |
| 
 | |
|     timer.stop(message);
 | |
|   }
 | |
|   /*
 | |
|       void PERFORMANCE_TEST()
 | |
|       {
 | |
|               cout << endl << endl;
 | |
|               cout << "Performance Test" << endl;
 | |
|               cout <<
 | |
|      "----------------------------------------------------------------------------------------" << endl; Timer
 | |
|      timer; int id; int numRows = 1000 * 1000 * 2; DoubleElementType el, el2, el3; WSDL<DoubleElementType>
 | |
|      wsdlIn(2, numRows); WSDL<DoubleElementType> wsdlIn2(2, numRows); WSDL<DoubleElementType> wsdlOut(1,
 | |
|      numRows);
 | |
| 
 | |
|               stringstream ss;
 | |
|               ss << "Loading " << numRows << " DoubleElementTypes into a WSDL.";
 | |
|               string message = ss.str();
 | |
|               timer.start(message);
 | |
| 
 | |
|               for(int i = 0; i < numRows; i++) {
 | |
|                       el.first = i;
 | |
|                       el.second = (i%5);
 | |
|                       wsdlIn.insert(el);
 | |
|               }
 | |
|               wsdlIn.endOfInput();
 | |
|               timer.stop(message);
 | |
| 
 | |
|               stringstream ss2;
 | |
|               ss2 << "Loading " << numRows << " DoubleElementTypes into a second WSDL.";
 | |
|               message = ss2.str();
 | |
|               timer.start(message);
 | |
| 
 | |
|               for(int i = 0; i < numRows; i++) {
 | |
|                       el.first = i;
 | |
|                       el.second = (i%5);
 | |
|                       wsdlIn2.insert(el);
 | |
|               }
 | |
|               wsdlIn2.endOfInput();
 | |
|               timer.stop(message);
 | |
| 
 | |
|               message = "Executing addition and loading result into a third WSDL.";
 | |
|               timer.start(message);
 | |
|               FunctionOperation fo;
 | |
|               fo.executeDrddFunction("+", wsdlIn, wsdlIn2, wsdlOut);
 | |
|               timer.stop(message);
 | |
|               wsdlOut.endOfInput();
 | |
| 
 | |
|               message = "Iterating over results and doing asserts.";
 | |
|               timer.start(message);
 | |
|               id = wsdlIn.getIterator();
 | |
|               int id2 = wsdlIn2.getIterator();
 | |
|               int id3 = wsdlOut.getIterator();
 | |
|               for(int i = 0; i < numRows; i++) {
 | |
|                       wsdlIn.next(id, &el);
 | |
|                       wsdlIn2.next(id2, &el2);
 | |
|                       wsdlOut.next(id3, &el3);
 | |
| 
 | |
|                       CPPUNIT_ASSERT(el.first == el3.first);
 | |
|                       CPPUNIT_ASSERT((el.second + el2.second) == el3.second);
 | |
| 
 | |
|               }
 | |
|               timer.stop(message);
 | |
|       }
 | |
|   */
 | |
| };
 | |
| 
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION(functionDriver);
 | |
| 
 | |
| int main(int argc, char** argv)
 | |
| {
 | |
|   CppUnit::TextUi::TestRunner runner;
 | |
|   CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
 | |
|   runner.addTest(registry.makeTest());
 | |
|   bool wasSuccessful = runner.run("", false);
 | |
|   return (wasSuccessful ? 0 : 1);
 | |
| }
 |