1 /* Copyright (C) 2014 InfiniDB, Inc.
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; version 2 of
6 the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301, USA. */
17
18 /****************************************************************************
19 * $Id: func_find_in_set.cpp 2675 2011-06-22 04:58:07Z chao $
20 *
21 *
22 ****************************************************************************/
23
24 #include <cstdlib>
25 #include <string>
26 #include <sstream>
27 using namespace std;
28
29 #include <boost/tokenizer.hpp>
30 using namespace boost;
31
32 #include "functor_int.h"
33 #include "functioncolumn.h"
34 #include "rowgroup.h"
35 #include "calpontsystemcatalog.h"
36 using namespace execplan;
37
38 #include "dataconvert.h"
39
40 #include "errorcodes.h"
41 #include "idberrorinfo.h"
42 #include "errorids.h"
43 using namespace logging;
44
45 #include "collation.h"
46
47 namespace funcexp
48 {
49
operationType(FunctionParm & fp,CalpontSystemCatalog::ColType & resultType)50 CalpontSystemCatalog::ColType Func_find_in_set::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
51 {
52 return resultType;
53 }
54
getIntVal(rowgroup::Row & row,FunctionParm & parm,bool & isNull,CalpontSystemCatalog::ColType & op_ct)55 int64_t Func_find_in_set::getIntVal(rowgroup::Row& row,
56 FunctionParm& parm,
57 bool& isNull,
58 CalpontSystemCatalog::ColType& op_ct)
59 {
60 const string& searchStr = parm[0]->data()->getStrVal(row, isNull);
61 if (isNull)
62 return 0;
63
64 const string& setString = parm[1]->data()->getStrVal(row, isNull);
65 if (isNull)
66 return 0;
67
68 if (searchStr.find(",") != string::npos)
69 return 0;
70
71 if (setString.length() < searchStr.length())
72 return 0;
73
74 CHARSET_INFO *cs= op_ct.getCharset();
75
76 my_wc_t wc= 0;
77 const char *str_begin = setString.c_str();
78 const char *str_end = setString.c_str();
79 const char *real_end = str_end + setString.length();
80 const char *find_str = searchStr.c_str();
81 size_t find_str_len = searchStr.length();
82 int position = 0;
83 static const char separator=',';
84 while (1)
85 {
86 int symbol_len;
87 if ((symbol_len= cs->mb_wc(&wc, (uchar*) str_end,
88 (uchar*) real_end)) > 0)
89 {
90 const char *substr_end = str_end + symbol_len;
91 bool is_last_item= (substr_end == real_end);
92 bool is_separator = (wc == (my_wc_t) separator);
93 if (is_separator || is_last_item)
94 {
95 position++;
96 if (is_last_item && !is_separator)
97 str_end = substr_end;
98 if (!cs->strnncoll(str_begin, (size_t) (str_end - str_begin),
99 find_str, find_str_len))
100 return (int64_t) position;
101 else
102 str_begin = substr_end;
103 }
104 str_end = substr_end;
105 }
106 else if (str_end - str_begin == 0 &&
107 find_str_len == 0 &&
108 wc == (my_wc_t) separator)
109 return (longlong) ++position;
110 else
111 return 0;
112 }
113 return 0;
114 }
115
getDoubleVal(rowgroup::Row & row,FunctionParm & parm,bool & isNull,execplan::CalpontSystemCatalog::ColType & ct)116 double Func_find_in_set::getDoubleVal(rowgroup::Row& row,
117 FunctionParm& parm,
118 bool& isNull,
119 execplan::CalpontSystemCatalog::ColType& ct)
120 {
121 return (double)getIntVal(row, parm, isNull, ct);
122 }
123
124
getStrVal(rowgroup::Row & row,FunctionParm & parm,bool & isNull,CalpontSystemCatalog::ColType & ct)125 string Func_find_in_set::getStrVal(rowgroup::Row& row,
126 FunctionParm& parm,
127 bool& isNull,
128 CalpontSystemCatalog::ColType& ct)
129 {
130 return intToString(getIntVal(row, parm, isNull, ct));
131 }
132
getDecimalVal(rowgroup::Row & row,FunctionParm & fp,bool & isNull,execplan::CalpontSystemCatalog::ColType & op_ct)133 execplan::IDB_Decimal Func_find_in_set::getDecimalVal(rowgroup::Row& row,
134 FunctionParm& fp,
135 bool& isNull,
136 execplan::CalpontSystemCatalog::ColType& op_ct)
137 {
138 IDB_Decimal decimal;
139 decimal.value = getIntVal(row, fp, isNull, op_ct);
140 decimal.scale = op_ct.scale;
141 return decimal;
142 }
143
144 } // namespace funcexp
145 // vim:ts=4 sw=4:
146