1 /* Copyright (C) 2014 InfiniDB, Inc.
2    Copyright (C) 2019 MariaDB Corporation
3 
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License
6    as published by the Free Software Foundation; version 2 of
7    the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17    MA 02110-1301, USA. */
18 
19 /***********************************************************************
20 *   $Id: functioncolumn.h 9679 2013-07-11 22:32:03Z zzhu $
21 *
22 *
23 ***********************************************************************/
24 /** @file */
25 
26 #ifndef FUNCTIONCOLUMN_H
27 #define FUNCTIONCOLUMN_H
28 #include <string>
29 #include <iosfwd>
30 #include <vector>
31 
32 #include "returnedcolumn.h"
33 #include "functor.h"
34 
35 namespace messageqcpp
36 {
37 class ByteStream;
38 }
39 
40 /**
41  * Namespace
42  */
43 namespace execplan
44 {
45 
46 /**
47  * @brief A class to represent a functional column
48  *
49  * This class is a specialization of class ReturnedColumn that
50  * handles a functional column like "extract(...)" and "substr(...)"
51  */
52 class FunctionColumn : public ReturnedColumn
53 {
54 
55 public:
56     FunctionColumn();
57     FunctionColumn(std::string& funcName);
58     FunctionColumn(const std::string& functionName, const std::string& funcParmsInString, const uint32_t sessionID = 0);
59     FunctionColumn( const FunctionColumn& rhs, const uint32_t sessionID = 0);
60     virtual ~FunctionColumn();
61 
62     /** get function name
63      *
64      * get the function name for this function column
65      */
functionName()66     inline const std::string& functionName() const
67     {
68         return fFunctionName;
69     }
70 
71     /** set function name
72      *
73      * set the function name for this function column
74      */
functionName(const std::string functionName)75     inline void functionName(const std::string functionName)
76     {
77         fFunctionName = functionName;
78     }
79 
80     /** get function parameters
81      *
82      * get the function parameters for this function column.
83      * @return a vector of paramenters in string format
84      */
functionParms()85     inline const funcexp::FunctionParm& functionParms() const
86     {
87         return fFunctionParms;
88     }
89 
90     /** set function parameters
91      *
92      * set the function parameters for this function column.
93      */
functionParms(const funcexp::FunctionParm & functionParms)94     void functionParms(const funcexp::FunctionParm& functionParms)
95     {
96         fFunctionParms = functionParms;
97     }
98 
99     /** set function parameters
100      *
101      * set the function parameters for this function column.
102      * pass in the functionParms with parenthesis as one string.
103      * tokenize the string with ' ' or ',' and form a vector of
104      * parameters in string.
105      */
106     void funcParms(const std::string& funcParmsInString);
107 
108     /** get table alias name
109      *
110      * get the table alias name for this function
111      */
tableAlias()112     inline const std::string& tableAlias () const
113     {
114         return fTableAlias;
115     }
116 
117     /** set table alias name
118      *
119      * set the table alias name for this function
120      */
tableAlias(const std::string & tableAlias)121     inline void tableAlias (const std::string& tableAlias)
122     {
123         fTableAlias = tableAlias;
124     }
125 
timeZone()126     inline const std::string timeZone () const
127     {
128         return fTimeZone;
129     }
130 
timeZone(const std::string & timeZone)131     inline void timeZone (const std::string& timeZone)
132     {
133         fTimeZone = timeZone;
134     }
135 
136     virtual const std::string data() const;
data(const std::string data)137     virtual void data(const std::string data)
138     {
139         fData = data;
140     }
141 
142     virtual const std::string toString() const;
143 
144     /** return a copy of this pointer
145      *
146      * deep copy of this pointer and return the copy
147      */
clone()148     inline virtual FunctionColumn* clone() const
149     {
150         return new FunctionColumn (*this);
151     }
152 
153     /**
154      * The serialization interface
155      */
156     virtual void serialize(messageqcpp::ByteStream&) const;
157     virtual void unserialize(messageqcpp::ByteStream&);
158 
159     using ReturnedColumn::hasAggregate;
160     virtual bool hasAggregate();
161     virtual bool hasWindowFunc();
162     virtual void setDerivedTable();
163     virtual void replaceRealCol(std::vector<SRCP>&);
simpleColumnList()164     virtual const std::vector<SimpleColumn*>& simpleColumnList() const
165     {
166         return fSimpleColumnList;
167     }
168 
169     virtual void setSimpleColumnList();
170     /**
171      * Return the tableAlias name of the table that the column arguments belong to.
172      *
173      * @param TableAliasName that will be set in the function
174      * @return true, if all arguments belong to one table
175      *         false, if multiple tables are involved in the function
176      */
177     virtual bool singleTable(CalpontSystemCatalog::TableAliasName& tan);
178 
179 private:
180     /**
181      * Fields
182      */
183     std::string fFunctionName;	/// function name
184     std::string fTableAlias;	/// table alias which has the column
185     std::string fData;			/// SQL representation
186     std::string fTimeZone;
187 
188     /** @brief Do a deep, strict (as opposed to semantic) equivalence test
189     *
190     * Do a deep, strict (as opposed to semantic) equivalence test.
191     * @return true iff every member of t is a duplicate copy of every member of this; false otherwise
192      */
193     virtual bool operator==(const TreeNode* t) const;
194 
195     /** @brief Do a deep, strict (as opposed to semantic) equivalence test
196      *
197      * Do a deep, strict (as opposed to semantic) equivalence test.
198      * @return true iff every member of t is a duplicate copy of every member of this; false otherwise
199      */
200     bool operator==(const FunctionColumn& t) const;
201 
202     /** @brief Do a deep, strict (as opposed to semantic) equivalence test
203      *
204      * Do a deep, strict (as opposed to semantic) equivalence test.
205      * @return false iff every member of t is a duplicate copy of every member of this; true otherwise
206      */
207     virtual bool operator!=(const TreeNode* t) const;
208 
209     /** @brief Do a deep, strict (as opposed to semantic) equivalence test
210      *
211      * Do a deep, strict (as opposed to semantic) equivalence test.
212      * @return false iff every member of t is a duplicate copy of every member of this; true otherwise
213      */
214     bool operator!=(const FunctionColumn& t) const;
215 
216     /***********************************************************
217      *				  F&E framework						  *
218      ***********************************************************/
219 public:
getStrVal(rowgroup::Row & row,bool & isNull)220     virtual const std::string& getStrVal(rowgroup::Row& row, bool& isNull)
221     {
222         fResult.strVal = fFunctor->getStrVal(row, fFunctionParms, isNull, fOperationType);
223         return fResult.strVal;
224     }
getIntVal(rowgroup::Row & row,bool & isNull)225     virtual int64_t getIntVal(rowgroup::Row& row, bool& isNull)
226     {
227         return fFunctor->getIntVal(row, fFunctionParms, isNull, fOperationType);
228     }
getUintVal(rowgroup::Row & row,bool & isNull)229     virtual uint64_t getUintVal(rowgroup::Row& row, bool& isNull)
230     {
231         return fFunctor->getUintVal(row, fFunctionParms, isNull, fOperationType);
232     }
getFloatVal(rowgroup::Row & row,bool & isNull)233     virtual float getFloatVal(rowgroup::Row& row, bool& isNull)
234     {
235         return fFunctor->getFloatVal(row, fFunctionParms, isNull, fOperationType);
236     }
getDoubleVal(rowgroup::Row & row,bool & isNull)237     virtual double getDoubleVal(rowgroup::Row& row, bool& isNull)
238     {
239         return fFunctor->getDoubleVal(row, fFunctionParms, isNull, fOperationType);
240     }
getLongDoubleVal(rowgroup::Row & row,bool & isNull)241     virtual long double getLongDoubleVal(rowgroup::Row& row, bool& isNull)
242     {
243         return fFunctor->getLongDoubleVal(row, fFunctionParms, isNull, fOperationType);
244     }
getDecimalVal(rowgroup::Row & row,bool & isNull)245     virtual IDB_Decimal getDecimalVal(rowgroup::Row& row, bool& isNull)
246     {
247         IDB_Decimal decimal = fFunctor->getDecimalVal(row, fFunctionParms, isNull, fOperationType);
248 
249         if (fResultType.scale == decimal.scale)
250             return decimal;
251 
252         if (fResultType.scale > decimal.scale)
253             decimal.value *= IDB_pow[fResultType.scale - decimal.scale];
254         else
255             decimal.value = (int64_t)(decimal.value > 0 ?
256                                       (double)decimal.value / IDB_pow[decimal.scale - fResultType.scale] + 0.5 :
257                                       (double)decimal.value / IDB_pow[decimal.scale - fResultType.scale] - 0.5);
258 
259         decimal.scale = fResultType.scale;
260         decimal.precision = fResultType.precision;
261         return decimal;
262     }
getBoolVal(rowgroup::Row & row,bool & isNull)263     virtual bool getBoolVal(rowgroup::Row& row, bool& isNull)
264     {
265         return fFunctor->getBoolVal(row, fFunctionParms, isNull, fOperationType);
266     }
getDateIntVal(rowgroup::Row & row,bool & isNull)267     virtual int32_t getDateIntVal(rowgroup::Row& row, bool& isNull)
268     {
269         return fFunctor->getDateIntVal(row, fFunctionParms, isNull, fOperationType);
270     }
getDatetimeIntVal(rowgroup::Row & row,bool & isNull)271     virtual int64_t getDatetimeIntVal(rowgroup::Row& row, bool& isNull)
272     {
273         return fFunctor->getDatetimeIntVal(row, fFunctionParms, isNull, fOperationType);
274     }
getTimestampIntVal(rowgroup::Row & row,bool & isNull)275     virtual int64_t getTimestampIntVal(rowgroup::Row& row, bool& isNull)
276     {
277         return fFunctor->getTimestampIntVal(row, fFunctionParms, isNull, fOperationType);
278     }
getTimeIntVal(rowgroup::Row & row,bool & isNull)279     virtual int64_t getTimeIntVal(rowgroup::Row& row, bool& isNull)
280     {
281         return fFunctor->getTimeIntVal(row, fFunctionParms, isNull, fOperationType);
282     }
283 
284 private:
285     funcexp::FunctionParm fFunctionParms;
286     funcexp::Func* fFunctor;   /// functor to execute this function
287     funcexp::Func* fDynamicFunctor = NULL; // for rand encode decode
288 };
289 
290 /**
291 * ostream operator
292 */
293 std::ostream& operator<<(std::ostream& output, const FunctionColumn& rhs);
294 
295 }
296 #endif //FUNCTIONCOLUMN_H
297 
298