Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
debug-util.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 "util/debug-util.h"
16 
17 #include <iomanip>
18 #include <sstream>
19 #include <boost/foreach.hpp>
20 
21 #include "common/version.h"
22 #include "runtime/descriptors.h"
23 #include "runtime/raw-value.h"
24 #include "runtime/tuple-row.h"
25 #include "runtime/row-batch.h"
26 #include "util/cpu-info.h"
27 #include "util/string-parser.h"
28 
29 // / WARNING this uses a private API of GLog: DumpStackTraceToString().
30 namespace google {
31 namespace glog_internal_namespace_ {
32 extern void DumpStackTraceToString(std::string* s);
33 }
34 }
35 
36 #include "common/names.h"
37 
38 using boost::char_separator;
39 using boost::tokenizer;
40 using namespace beeswax;
41 using namespace parquet;
42 
43 namespace impala {
44 
45 #define THRIFT_ENUM_OUTPUT_FN_IMPL(E, MAP) \
46  ostream& operator<<(ostream& os, const E::type& e) {\
47  map<int, const char*>::const_iterator i;\
48  i = MAP.find(e);\
49  if (i != MAP.end()) {\
50  os << i->second;\
51  }\
52  return os;\
53  }
54 
55 // Macro to stamp out operator<< for thrift enums. Why doesn't thrift do this?
56 #define THRIFT_ENUM_OUTPUT_FN(E) THRIFT_ENUM_OUTPUT_FN_IMPL(E , _##E##_VALUES_TO_NAMES)
57 
58 // Macro to implement Print function that returns string for thrift enums
59 #define THRIFT_ENUM_PRINT_FN(E) \
60  string Print##E(const E::type& e) {\
61  stringstream ss;\
62  ss << e;\
63  return ss.str();\
64  }
65 
66 THRIFT_ENUM_OUTPUT_FN(TFunctionBinaryType);
67 THRIFT_ENUM_OUTPUT_FN(TCatalogObjectType);
68 THRIFT_ENUM_OUTPUT_FN(TDdlType);
69 THRIFT_ENUM_OUTPUT_FN(TCatalogOpType);
70 THRIFT_ENUM_OUTPUT_FN(THdfsFileFormat);
71 THRIFT_ENUM_OUTPUT_FN(THdfsCompression);
72 THRIFT_ENUM_OUTPUT_FN(TSessionType);
73 THRIFT_ENUM_OUTPUT_FN(TStmtType);
74 THRIFT_ENUM_OUTPUT_FN(QueryState);
75 THRIFT_ENUM_OUTPUT_FN(Encoding);
76 THRIFT_ENUM_OUTPUT_FN(CompressionCodec);
78 THRIFT_ENUM_OUTPUT_FN(TMetricKind);
80 
81 THRIFT_ENUM_PRINT_FN(TCatalogObjectType);
82 THRIFT_ENUM_PRINT_FN(TDdlType);
83 THRIFT_ENUM_PRINT_FN(TCatalogOpType);
84 THRIFT_ENUM_PRINT_FN(TSessionType);
85 THRIFT_ENUM_PRINT_FN(TStmtType);
86 THRIFT_ENUM_PRINT_FN(QueryState);
87 THRIFT_ENUM_PRINT_FN(Encoding);
88 THRIFT_ENUM_PRINT_FN(TMetricKind);
90 
91 
92 ostream& operator<<(ostream& os, const TUniqueId& id) {
93  os << PrintId(id);
94  return os;
95 }
96 
97 string PrintId(const TUniqueId& id, const string& separator) {
98  stringstream out;
99  out << hex << id.hi << separator << id.lo;
100  return out.str();
101 }
102 
103 string PrintAsHex(const char* bytes, int64_t len) {
104  stringstream out;
105  out << hex << std::setfill('0');
106  for (int i = 0; i < len; ++i) {
107  out << setw(2) << static_cast<uint16_t>(bytes[i]);
108  }
109  return out.str();
110 }
111 
112 bool ParseId(const string& s, TUniqueId* id) {
113  // For backwards compatibility, this method parses two forms of query ID from text:
114  // - <hex-int64_t><colon><hex-int64_t> - this format is the standard going forward
115  // - <decimal-int64_t><space><decimal-int64_t> - legacy compatibility with CDH4 CM
116  DCHECK(id != NULL);
117 
118  const char* hi_part = s.c_str();
119  char* separator = const_cast<char*>(strchr(hi_part, ':'));
120  if (separator == NULL) {
121  // Legacy compatibility branch
122  char_separator<char> sep(" ");
123  tokenizer< char_separator<char> > tokens(s, sep);
124  int i = 0;
125  BOOST_FOREACH(const string& token, tokens) {
126  StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS;
127  int64_t component = StringParser::StringToInt<int64_t>(
128  token.c_str(), token.length(), &parse_result);
129  if (parse_result != StringParser::PARSE_SUCCESS) return false;
130  if (i == 0) {
131  id->hi = component;
132  } else if (i == 1) {
133  id->lo = component;
134  } else {
135  // Too many tokens, must be ill-formed.
136  return false;
137  }
138  ++i;
139  }
140  return true;
141  }
142 
143  // Parse an ID from <int64_t_as_hex><colon><int64_t_as_hex>
144  const char* lo_part = separator + 1;
145  *separator = '\0';
146 
147  char* error_hi = NULL;
148  char* error_lo = NULL;
149  id->hi = strtoul(hi_part, &error_hi, 16);
150  id->lo = strtoul(lo_part, &error_lo, 16);
151 
152  bool valid = *error_hi == '\0' && *error_lo == '\0';
153  *separator = ':';
154  return valid;
155 }
156 
157 string PrintPlanNodeType(const TPlanNodeType::type& type) {
158  map<int, const char*>::const_iterator i;
159  i = _TPlanNodeType_VALUES_TO_NAMES.find(type);
160  if (i != _TPlanNodeType_VALUES_TO_NAMES.end()) {
161  return i->second;
162  }
163  return "Invalid plan node type";
164 }
165 
166 string PrintTuple(const Tuple* t, const TupleDescriptor& d) {
167  if (t == NULL) return "null";
168  stringstream out;
169  out << "(";
170  bool first_value = true;
171  for (int i = 0; i < d.slots().size(); ++i) {
172  SlotDescriptor* slot_d = d.slots()[i];
173  if (!slot_d->is_materialized()) continue;
174  if (first_value) {
175  first_value = false;
176  } else {
177  out << " ";
178  }
179  if (t->IsNull(slot_d->null_indicator_offset())) {
180  out << "null";
181  } else {
182  string value_str;
183  RawValue::PrintValue(
184  t->GetSlot(slot_d->tuple_offset()), slot_d->type(), -1, &value_str);
185  out << value_str;
186  }
187  }
188  out << ")";
189  return out.str();
190 }
191 
192 string PrintRow(TupleRow* row, const RowDescriptor& d) {
193  stringstream out;
194  out << "[";
195  for (int i = 0; i < d.tuple_descriptors().size(); ++i) {
196  if (i != 0) out << " ";
197  out << PrintTuple(row->GetTuple(i), *d.tuple_descriptors()[i]);
198  }
199  out << "]";
200  return out.str();
201 }
202 
203 string PrintBatch(RowBatch* batch) {
204  stringstream out;
205  for (int i = 0; i < batch->num_rows(); ++i) {
206  out << PrintRow(batch->GetRow(i), batch->row_desc()) << "\n";
207  }
208  return out.str();
209 }
210 
211 string PrintPath(const vector<int>& path) {
212  stringstream ss;
213  ss << "[";
214  if (path.size() > 0) ss << path[0];
215  for (int i = 1; i < path.size(); ++i) {
216  ss << " ";
217  ss << path[i];
218  }
219  ss << "]";
220  return ss.str();
221 }
222 
223 string GetBuildVersion(bool compact) {
224  stringstream ss;
226 #ifdef NDEBUG
227  << " RELEASE"
228 #else
229  << " DEBUG"
230 #endif
231  << " (build " << IMPALA_BUILD_HASH
232  << ")";
233  if (!compact) {
234  ss << endl << "Built on " << IMPALA_BUILD_TIME;
235  }
236  return ss.str();
237 }
238 
239 string GetVersionString(bool compact) {
240  stringstream ss;
241  ss << google::ProgramInvocationShortName()
242  << " version " << GetBuildVersion(compact);
243  return ss.str();
244 }
245 
246 string GetStackTrace() {
247  string s;
249  return s;
250 }
251 
252 }
int num_rows() const
Definition: row-batch.h:215
string path("/usr/lib/sasl2:/usr/lib64/sasl2:/usr/local/lib/sasl2:/usr/lib/x86_64-linux-gnu/sasl2")
#define IMPALA_BUILD_TIME
Definition: version.h:23
bool ParseId(const string &s, TUniqueId *id)
Definition: debug-util.cc:112
Tuple * GetTuple(int tuple_idx)
Definition: tuple-row.h:30
#define IMPALA_BUILD_HASH
Definition: version.h:22
A tuple with 0 materialised slots is represented as NULL.
Definition: tuple.h:48
const RowDescriptor & row_desc() const
Definition: row-batch.h:218
string GetVersionString(bool compact)
Returns "<program short name> version <GetBuildVersion(compact)>".
Definition: debug-util.cc:239
string PrintPath(const vector< int > &path)
Definition: debug-util.cc:211
TupleRow * GetRow(int row_idx)
Definition: row-batch.h:140
ostream & operator<<(ostream &os, const TUniqueId &id)
Definition: debug-util.cc:92
void * GetSlot(int offset)
Definition: tuple.h:118
string GetBuildVersion(bool compact)
Definition: debug-util.cc:223
const std::vector< SlotDescriptor * > & slots() const
Definition: descriptors.h:302
string PrintId(const TUniqueId &id, const string &separator)
Definition: debug-util.cc:97
const NullIndicatorOffset & null_indicator_offset() const
Definition: descriptors.h:89
bool IsNull(const NullIndicatorOffset &offset) const
Definition: tuple.h:112
const ColumnType & type() const
Definition: descriptors.h:78
#define THRIFT_ENUM_PRINT_FN(E)
Definition: debug-util.cc:59
string PrintBatch(RowBatch *batch)
Definition: debug-util.cc:203
const std::vector< TupleDescriptor * > & tuple_descriptors() const
Return descriptors for all tuples in this row, in order of appearance.
Definition: descriptors.h:412
string PrintPlanNodeType(const TPlanNodeType::type &type)
Definition: debug-util.cc:157
void DumpStackTraceToString(std::string *s)
int tuple_offset() const
Definition: descriptors.h:88
#define IMPALA_BUILD_VERSION
Definition: version.h:21
#define THRIFT_ENUM_OUTPUT_FN(E)
Definition: debug-util.cc:56
bool is_materialized() const
Definition: descriptors.h:92
string GetStackTrace()
Definition: debug-util.cc:246
string PrintRow(TupleRow *row, const RowDescriptor &d)
Definition: debug-util.cc:192
string PrintTuple(const Tuple *t, const TupleDescriptor &d)
Definition: debug-util.cc:166
string PrintAsHex(const char *bytes, int64_t len)
Definition: debug-util.cc:103