Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
symbols-util-test.cc
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <iostream>
18 #include <gtest/gtest.h>
19 
20 #include "codegen/llvm-codegen.h"
21 #include "util/symbols-util.h"
22 
23 #include "common/names.h"
24 
25 namespace impala {
26 
27 void TestDemangling(const string& mangled, const string& expected_demangled) {
28  string result = SymbolsUtil::Demangle(mangled);
29  EXPECT_EQ(result, expected_demangled);
30 }
31 
32 void TestDemanglingNameOnly(const string& mangled, const string& expected_demangled) {
33  string result = SymbolsUtil::DemangleNameOnly(mangled);
34  EXPECT_EQ(result, expected_demangled);
35 }
36 
37 // Test mangling (name, var_args, args, ret_arg_type), validating the mangled
38 // string and then the unmangled (~function signature) results.
39 void TestMangling(const string& name, bool var_args, const vector<ColumnType> args,
40  ColumnType* ret_arg_type, const string& expected_mangled,
41  const string& expected_demangled) {
42  string mangled = SymbolsUtil::MangleUserFunction(name, args, var_args, ret_arg_type);
43  string demangled = SymbolsUtil::Demangle(mangled);
44 
45  // Check we could demangle it.
46  EXPECT_TRUE(!demangled.empty()) << demangled;
47  EXPECT_EQ(mangled, expected_mangled);
48  EXPECT_EQ(demangled, expected_demangled);
49 }
50 
51 void TestManglingPrepareOrClose(const string& name, const string& expected_mangled,
52  const string& expected_demangled) {
53  string mangled = SymbolsUtil::ManglePrepareOrCloseFunction(name);
54  string demangled = SymbolsUtil::Demangle(mangled);
55 
56  // Check we could demangle it.
57  EXPECT_TRUE(!demangled.empty()) << demangled;
58  EXPECT_EQ(mangled, expected_mangled);
59  EXPECT_EQ(demangled, expected_demangled);
60 }
61 
62 // Not very thoroughly tested since our implementation is just a wrapper around
63 // the gcc library.
64 TEST(SymbolsUtil, Demangling) {
65  TestDemangling("_Z6NoArgsPN10impala_udf15FunctionContextE",
66  "NoArgs(impala_udf::FunctionContext*)");
67  TestDemangling("_Z8IdentityPN10impala_udf15FunctionContextERKNS_10TinyIntValE",
68  "Identity(impala_udf::FunctionContext*, impala_udf::TinyIntVal const&)");
69  TestDemangling("_Z8IdentityPN10impala_udf15FunctionContextERKNS_9StringValE",
70  "Identity(impala_udf::FunctionContext*, impala_udf::StringVal const&)");
71  TestDemangling("_ZN3Foo4TESTEPN10impala_udf15FunctionContextERKNS0_6IntValES5_",
72  "Foo::TEST(impala_udf::FunctionContext*, impala_udf::IntVal const&, "
73  "impala_udf::IntVal const&)");
75  "_Z14VarSumMultiplyPN10impala_udf15FunctionContextERKNS_9DoubleValEiPKNS_6IntValE",
76  "VarSumMultiply(impala_udf::FunctionContext*, impala_udf::DoubleVal const&, int, "
77  "impala_udf::IntVal const*)");
78  TestDemangling("FooBar", "");
79 }
80 
81 // Not very thoroughly tested since our implementation is just a wrapper around
82 // the gcc library.
83 TEST(SymbolsUtil, DemanglingNameOnly) {
84  TestDemanglingNameOnly("_Z6NoArgsPN10impala_udf15FunctionContextE", "NoArgs");
85  TestDemanglingNameOnly("_Z8IdentityPN10impala_udf15FunctionContextERKNS_10TinyIntValE",
86  "Identity");
87  TestDemanglingNameOnly("_Z8IdentityPN10impala_udf15FunctionContextERKNS_9StringValE",
88  "Identity");
89  TestDemanglingNameOnly("_ZN3Foo4TESTEPN10impala_udf15FunctionContextERKNS0_6IntValES5_",
90  "TEST");
92  "_Z14VarSumMultiplyPN10impala_udf15FunctionContextERKNS_9DoubleValEiPKNS_6IntValE",
93  "VarSumMultiply");
94  TestDemangling("FooBar", "");
95 }
96 
97 // TODO: is there a less arduous way to test this?
98 TEST(SymbolsUtil, Mangling) {
99  ColumnType int_ret_type = ColumnType(TYPE_INT);
100  ColumnType double_ret_type = ColumnType(TYPE_DOUBLE);
101 
102  vector<ColumnType> args;
103  TestMangling("Foo", false, args, NULL, "_Z3FooPN10impala_udf15FunctionContextE",
104  "Foo(impala_udf::FunctionContext*)");
105  TestMangling("Foo", false, args, &int_ret_type,
106  "_Z3FooPN10impala_udf15FunctionContextEPNS_6IntValE",
107  "Foo(impala_udf::FunctionContext*, impala_udf::IntVal*)");
108  TestMangling("A::B", false, args, NULL, "_ZN1A1BEPN10impala_udf15FunctionContextE",
109  "A::B(impala_udf::FunctionContext*)");
110  TestMangling("A::B::C", false, args, NULL, "_ZN1A1B1CEPN10impala_udf15FunctionContextE",
111  "A::B::C(impala_udf::FunctionContext*)");
112  TestMangling("A::B::C", false, args, &int_ret_type,
113  "_ZN1A1B1CEPN10impala_udf15FunctionContextEPNS1_6IntValE",
114  "A::B::C(impala_udf::FunctionContext*, impala_udf::IntVal*)");
115 
116  // Try functions with in input INT arg. Then try with varargs and int* return arg.
117  args.push_back(TYPE_INT);
118  TestMangling("F", false, args, NULL,
119  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValE",
120  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&)");
121  TestMangling("F", false, args, &int_ret_type,
122  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValEPS2_",
123  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, impala_udf::IntVal*)");
124  TestMangling("F", true, args, NULL,
125  "_Z1FPN10impala_udf15FunctionContextEiPKNS_6IntValE",
126  "F(impala_udf::FunctionContext*, int, impala_udf::IntVal const*)");
127  TestMangling("F", true, args, &int_ret_type,
128  "_Z1FPN10impala_udf15FunctionContextEiPKNS_6IntValEPS2_",
129  "F(impala_udf::FunctionContext*, int, impala_udf::IntVal const*, "
130  "impala_udf::IntVal*)");
131  TestMangling("F::B", false, args, NULL,
132  "_ZN1F1BEPN10impala_udf15FunctionContextERKNS0_6IntValE",
133  "F::B(impala_udf::FunctionContext*, impala_udf::IntVal const&)");
134  TestMangling("F::B::C::D", false, args, NULL,
135  "_ZN1F1B1C1DEPN10impala_udf15FunctionContextERKNS2_6IntValE",
136  "F::B::C::D(impala_udf::FunctionContext*, impala_udf::IntVal const&)");
137  TestMangling("F::B", true, args, NULL,
138  "_ZN1F1BEPN10impala_udf15FunctionContextEiPKNS0_6IntValE",
139  "F::B(impala_udf::FunctionContext*, int, impala_udf::IntVal const*)");
140  TestMangling("F::B", true, args, &int_ret_type,
141  "_ZN1F1BEPN10impala_udf15FunctionContextEiPKNS0_6IntValEPS3_",
142  "F::B(impala_udf::FunctionContext*, int, impala_udf::IntVal const*, "
143  "impala_udf::IntVal*)");
144 
145  // Try addding some redudant argument types. These should get compressed away.
146  args.push_back(TYPE_INT);
147  TestMangling("F", false, args, NULL,
148  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValES4_",
149  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, "
150  "impala_udf::IntVal const&)");
151  TestMangling("F", false, args, &int_ret_type,
152  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValES4_PS2_",
153  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, "
154  "impala_udf::IntVal const&, impala_udf::IntVal*)");
155  TestMangling("F", true, args, NULL,
156  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValEiPS3_",
157  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, int, "
158  "impala_udf::IntVal const*)");
159  TestMangling("F", true, args, &int_ret_type,
160  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValEiPS3_PS2_",
161  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, int, "
162  "impala_udf::IntVal const*, impala_udf::IntVal*)");
163  TestMangling("F::B", false, args, NULL,
164  "_ZN1F1BEPN10impala_udf15FunctionContextERKNS0_6IntValES5_",
165  "F::B(impala_udf::FunctionContext*, impala_udf::IntVal const&, "
166  "impala_udf::IntVal const&)");
167 
168  args.push_back(TYPE_INT);
169  TestMangling("F", false, args, NULL,
170  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValES4_S4_",
171  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, "
172  "impala_udf::IntVal const&, impala_udf::IntVal const&)");
173  TestMangling("F", false, args, &int_ret_type,
174  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValES4_S4_PS2_",
175  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, "
176  "impala_udf::IntVal const&, impala_udf::IntVal const&, "
177  "impala_udf::IntVal*)");
178  TestMangling("F", false, args, &double_ret_type,
179  "_Z1FPN10impala_udf15FunctionContextERKNS_6IntValES4_S4_PNS_9DoubleValE",
180  "F(impala_udf::FunctionContext*, impala_udf::IntVal const&, "
181  "impala_udf::IntVal const&, impala_udf::IntVal const&, "
182  "impala_udf::DoubleVal*)");
183 
184  // Try some more complicated cases.
185  // fn(double, double, int, int)
186  args.clear();
187  args.push_back(TYPE_DOUBLE);
188  args.push_back(TYPE_DOUBLE);
189  args.push_back(TYPE_INT);
190  args.push_back(TYPE_INT);
191  TestMangling("TEST", false, args, NULL,
192  "_Z4TESTPN10impala_udf15FunctionContextERKNS_9DoubleValES4_RKNS_6IntValES7_",
193  "TEST(impala_udf::FunctionContext*, impala_udf::DoubleVal const&, "
194  "impala_udf::DoubleVal const&, impala_udf::IntVal const&, "
195  "impala_udf::IntVal const&)");
196  TestMangling("TEST", true, args, NULL,
197  "_Z4TESTPN10impala_udf15FunctionContextERKNS_9DoubleValES4_RKNS_6IntValEiPS6_",
198  "TEST(impala_udf::FunctionContext*, impala_udf::DoubleVal const&, "
199  "impala_udf::DoubleVal const&, impala_udf::IntVal const&, int, "
200  "impala_udf::IntVal const*)");
201  TestMangling("TEST", false, args, &int_ret_type,
202  "_Z4TESTPN10impala_udf15FunctionContextERKNS_9DoubleValES4_RKNS_6IntValES7_PS5_",
203  "TEST(impala_udf::FunctionContext*, impala_udf::DoubleVal const&, "
204  "impala_udf::DoubleVal const&, impala_udf::IntVal const&, "
205  "impala_udf::IntVal const&, impala_udf::IntVal*)");
206  TestMangling("TEST", true, args, &double_ret_type,
207  "_Z4TESTPN10impala_udf15FunctionContextERKNS_9DoubleValES4_RKNS_6IntValEiPS6_PS2_",
208  "TEST(impala_udf::FunctionContext*, impala_udf::DoubleVal const&, "
209  "impala_udf::DoubleVal const&, impala_udf::IntVal const&, int, "
210  "impala_udf::IntVal const*, impala_udf::DoubleVal*)");
211 
212  // fn(int, double, double, int)
213  args.clear();
214  args.push_back(TYPE_INT);
215  args.push_back(TYPE_DOUBLE);
216  args.push_back(TYPE_DOUBLE);
217  args.push_back(TYPE_INT);
218  TestMangling("TEST", false, args, NULL,
219  "_Z4TESTPN10impala_udf15FunctionContextERKNS_6IntValERKNS_9DoubleValES7_S4_",
220  "TEST(impala_udf::FunctionContext*, impala_udf::IntVal const&, impala_udf::"
221  "DoubleVal const&, impala_udf::DoubleVal const&, impala_udf::IntVal const&)");
222  TestMangling("TEST", true, args, NULL,
223  "_Z4TESTPN10impala_udf15FunctionContextERKNS_6IntValERKNS_9DoubleValES7_iPS3_",
224  "TEST(impala_udf::FunctionContext*, impala_udf::IntVal const&, impala_udf::"
225  "DoubleVal const&, impala_udf::DoubleVal const&, int, "
226  "impala_udf::IntVal const*)");
227 
228  // All the types.
229  args.clear();
230  args.push_back(TYPE_STRING);
231  args.push_back(TYPE_BOOLEAN);
232  args.push_back(TYPE_TINYINT);
233  args.push_back(TYPE_SMALLINT);
234  args.push_back(TYPE_INT);
235  args.push_back(TYPE_BIGINT);
236  args.push_back(TYPE_FLOAT);
237  args.push_back(TYPE_DOUBLE);
238  args.push_back(TYPE_TIMESTAMP);
239  args.push_back(ColumnType::CreateCharType(10));
240  TestMangling("AllTypes", false, args, NULL,
241  "_Z8AllTypesPN10impala_udf15FunctionContextERKNS_9StringValERKNS_10"
242  "BooleanValERKNS_10TinyIntValERKNS_11SmallIntValERKNS_6IntValERKNS_9BigIntVal"
243  "ERKNS_8FloatValERKNS_9DoubleValERKNS_12TimestampValERKNS_9StringValE",
244  "AllTypes(impala_udf::FunctionContext*, impala_udf::StringVal const&, "
245  "impala_udf::BooleanVal const&, impala_udf::TinyIntVal const&, "
246  "impala_udf::SmallIntVal const&, impala_udf::IntVal const&, "
247  "impala_udf::BigIntVal const&, impala_udf::FloatVal const&, "
248  "impala_udf::DoubleVal const&, impala_udf::TimestampVal const&, "
249  "impala_udf::StringVal const&)");
250  TestMangling("AllTypes", false, args, &int_ret_type,
251  "_Z8AllTypesPN10impala_udf15FunctionContextERKNS_9StringValERKNS_10BooleanValE"
252  "RKNS_10TinyIntValERKNS_11SmallIntValERKNS_6IntValERKNS_9BigIntValE"
253  "RKNS_8FloatValERKNS_9DoubleValERKNS_12TimestampValERKNS_9StringValEPSE_",
254  "AllTypes(impala_udf::FunctionContext*, impala_udf::StringVal const&, "
255  "impala_udf::BooleanVal const&, impala_udf::TinyIntVal const&, "
256  "impala_udf::SmallIntVal const&, impala_udf::IntVal const&, "
257  "impala_udf::BigIntVal const&, impala_udf::FloatVal const&, "
258  "impala_udf::DoubleVal const&, impala_udf::TimestampVal const&, "
259  "impala_udf::StringVal const&, impala_udf::IntVal*)");
260  TestMangling("AllTypes", false, args, &double_ret_type,
261  "_Z8AllTypesPN10impala_udf15FunctionContextERKNS_9StringValERKNS_10BooleanValE"
262  "RKNS_10TinyIntValERKNS_11SmallIntValERKNS_6IntValERKNS_9BigIntValE"
263  "RKNS_8FloatValERKNS_9DoubleValERKNS_12TimestampValERKNS_9StringValEPSN_",
264  "AllTypes(impala_udf::FunctionContext*, impala_udf::StringVal const&, "
265  "impala_udf::BooleanVal const&, impala_udf::TinyIntVal const&, "
266  "impala_udf::SmallIntVal const&, impala_udf::IntVal const&, "
267  "impala_udf::BigIntVal const&, impala_udf::FloatVal const&, "
268  "impala_udf::DoubleVal const&, impala_udf::TimestampVal const&, "
269  "impala_udf::StringVal const&, impala_udf::DoubleVal*)");
270 
271  // CHAR(N) type. This has restricted use. It can only be an intermediate type.
272  args.clear();
273  ColumnType char_ret_type = ColumnType::CreateCharType(10);
274  TestMangling("TEST", false, args, &char_ret_type,
275  "_Z4TESTPN10impala_udf15FunctionContextEPNS_9StringValE",
276  "TEST(impala_udf::FunctionContext*, impala_udf::StringVal*)");
277  args.push_back(ColumnType::CreateCharType(10));
278  TestMangling("TEST", false, args, &char_ret_type,
279  "_Z4TESTPN10impala_udf15FunctionContextERKNS_9StringValEPS2_",
280  "TEST(impala_udf::FunctionContext*, impala_udf::StringVal const&, "
281  "impala_udf::StringVal*)");
282 }
283 
284 TEST(SymbolsUtil, ManglingPrepareOrClose) {
285  TestManglingPrepareOrClose("CountPrepare",
286  "_Z12CountPreparePN10impala_udf15FunctionContextENS0_18FunctionStateScopeE",
287  "CountPrepare(impala_udf::FunctionContext*,"
288  " impala_udf::FunctionContext::FunctionStateScope)");
289  TestManglingPrepareOrClose("foo::bar",
290  "_ZN3foo3barEPN10impala_udf15FunctionContextENS1_18FunctionStateScopeE",
291  "foo::bar(impala_udf::FunctionContext*,"
292  " impala_udf::FunctionContext::FunctionStateScope)");
293 }
294 
295 }
296 
297 int main(int argc, char **argv) {
298  ::testing::InitGoogleTest(&argc, argv);
300  return RUN_ALL_TESTS();
301 }
TEST(AtomicTest, Basic)
Definition: atomic-test.cc:28
static std::string ManglePrepareOrCloseFunction(const std::string &fn_name)
Utility class to manipulate c++/IR symbols, mangling and demangling names.
Definition: symbols-util.h:24
static ColumnType CreateCharType(int len)
Definition: types.h:85
static std::string Demangle(const std::string &name)
Definition: symbols-util.cc:57
void TestDemanglingNameOnly(const string &mangled, const string &expected_demangled)
void TestDemangling(const string &mangled, const string &expected_demangled)
static void InitializeLlvm(bool load_backend=false)
Definition: llvm-codegen.cc:78
void TestMangling(const string &name, bool var_args, const vector< ColumnType > args, ColumnType *ret_arg_type, const string &expected_mangled, const string &expected_demangled)
void TestManglingPrepareOrClose(const string &name, const string &expected_mangled, const string &expected_demangled)
int main(int argc, char **argv)
static std::string MangleUserFunction(const std::string &fn_name, const std::vector< ColumnType > &arg_types, bool has_var_args=false, ColumnType *ret_argument=NULL)
string name
Definition: cpu-info.cc:50
static std::string DemangleNameOnly(const std::string &symbol)
Definition: symbols-util.cc:66