Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
error-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/error-util.h"
16 
17 #include <boost/foreach.hpp>
18 
19 #include <errno.h>
20 #include <string.h>
21 #include <sstream>
22 
23 using std::string;
24 using std::stringstream;
25 using std::vector;
26 using std::ostream;
27 
28 namespace impala {
29 
30 string GetStrErrMsg() {
31  // Save errno. "<<" could reset it.
32  int e = errno;
33  if (e == 0) return "";
34  stringstream ss;
35  char buf[1024];
36  ss << "Error(" << e << "): " << strerror_r(e, buf, 1024);
37  return ss.str();
38 }
39 
40 string GetTablesMissingStatsWarning(const vector<TTableName>& tables_missing_stats) {
41  stringstream ss;
42  if (tables_missing_stats.empty()) return string("");
43  ss << "WARNING: The following tables are missing relevant table and/or column "
44  << "statistics.\n";
45  for (int i = 0; i < tables_missing_stats.size(); ++i) {
46  const TTableName& table_name = tables_missing_stats[i];
47  if (i != 0) ss << ",";
48  ss << table_name.db_name << "." << table_name.table_name;
49  }
50  return ss.str();
51 }
52 
53 ErrorMsg::ErrorMsg(TErrorCode::type error)
54  : error_(error),
55  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_])) {}
56 
57 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0)
58  : error_(error),
59  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
60  arg0)) {}
61 
62 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1)
63  : error_(error),
64  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
65  arg0, arg1)) {}
66 
67 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
68  const ArgType& arg2)
69  : error_(error),
70  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
71  arg0, arg1, arg2)) {}
72 
73 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
74  const ArgType& arg2, const ArgType& arg3)
75  : error_(error),
76  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
77  arg0, arg1, arg2, arg3)) {}
78 
79 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
80  const ArgType& arg2, const ArgType& arg3, const ArgType& arg4)
81  : error_(error),
82  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
83  arg0, arg1, arg2, arg3, arg4)) {}
84 
85 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
86  const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
87  const ArgType& arg5)
88  : error_(error),
89  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
90  arg0, arg1, arg2, arg3, arg4, arg5)) {}
91 
92 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
93  const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
94  const ArgType& arg5, const ArgType& arg6)
95  : error_(error),
96  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
97  arg0, arg1, arg2, arg3, arg4, arg5, arg6)) {}
98 
99 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
100  const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
101  const ArgType& arg5, const ArgType& arg6, const ArgType& arg7)
102  : error_(error),
103  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
104  arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)) {}
105 
106 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
107  const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
108  const ArgType& arg5, const ArgType& arg6, const ArgType& arg7,
109  const ArgType& arg8)
110  : error_(error),
111  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
112  arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)) {}
113 
114 ErrorMsg::ErrorMsg(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
115  const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
116  const ArgType& arg5, const ArgType& arg6, const ArgType& arg7,
117  const ArgType& arg8, const ArgType& arg9)
118  : error_(error),
119  message_(strings::Substitute(g_ErrorCodes_constants.TErrorMessage[error_],
120  arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)) {}
121 
122 ErrorMsg ErrorMsg::Init(TErrorCode::type error, const ArgType& arg0,
123  const ArgType& arg1, const ArgType& arg2, const ArgType& arg3,
124  const ArgType& arg4, const ArgType& arg5, const ArgType& arg6, const ArgType& arg7,
125  const ArgType& arg8, const ArgType& arg9) {
126 
127  ErrorCodesConstants error_strings;
128  ErrorMsg m;
129  m.error_ = error;
130  m.message_ = strings::Substitute(error_strings.TErrorMessage[m.error_],
131  arg0, arg1, arg2, arg3, arg4, arg5,
132  arg6, arg7, arg8, arg9);
133  return m;
134 }
135 
136 void PrintErrorMap(ostream* stream, const ErrorLogMap& errors) {
137  BOOST_FOREACH(const ErrorLogMap::value_type& v, errors) {
138  if (v.first == TErrorCode::GENERAL) {
139  BOOST_FOREACH(const string& s, v.second.messages) {
140  *stream << s << "\n";
141  }
142  } else {
143  *stream << v.second.messages.front();
144  if (v.second.count < 2) {
145  *stream << "\n";
146  } else {
147  *stream << " (1 of " << v.second.count << " similar)\n";
148  }
149  }
150  }
151 }
152 
153 string PrintErrorMapToString(const ErrorLogMap& errors) {
154  stringstream stream;
155  PrintErrorMap(&stream, errors);
156  return stream.str();
157 }
158 
159 void MergeErrorMaps(ErrorLogMap* left, const ErrorLogMap& right) {
160  BOOST_FOREACH(const ErrorLogMap::value_type& v, right) {
161  // Append generic message, append specific codes or increment count if exists
162  if (v.first == TErrorCode::GENERAL) {
163  (*left)[v.first].messages.insert(
164  (*left)[v.first].messages.end(), v.second.messages.begin(),
165  v.second.messages.end());
166  } else {
167  if ((*left).count(v.first) > 0) {
168  (*left)[v.first].count += v.second.count;
169  } else {
170  (*left)[v.first].messages.push_back(v.second.messages.front());
171  (*left)[v.first].count = v.second.count;
172  }
173  }
174  }
175 }
176 
177 void AppendError(ErrorLogMap* map, const ErrorMsg& e) {
178  if (e.error() == TErrorCode::GENERAL) {
179  (*map)[e.error()].messages.push_back(e.msg());
180  } else {
181  ErrorLogMap::iterator it = map->find(e.error());
182  if (it != map->end()) {
183  ++(it->second.count);
184  } else {
185  (*map)[e.error()].messages.push_back(e.msg());
186  (*map)[e.error()].count = 1;
187  }
188  }
189 }
190 
191 size_t ErrorCount(const ErrorLogMap& errors) {
192  ErrorLogMap::const_iterator cit = errors.find(TErrorCode::GENERAL);
193  size_t general_errors = cit != errors.end() ?
194  errors.find(TErrorCode::GENERAL)->second.messages.size() - 1 : 0;
195  return errors.size() + general_errors;
196 }
197 
198 }
const std::string & msg() const
Returns the formatted error string.
Definition: error-util.h:118
string GetTablesMissingStatsWarning(const vector< TTableName > &tables_missing_stats)
Definition: error-util.cc:40
string PrintErrorMapToString(const ErrorLogMap &errors)
Definition: error-util.cc:153
TErrorCode::type error_
Definition: error-util.h:138
TErrorCode::type error() const
Definition: error-util.h:105
void MergeErrorMaps(ErrorLogMap *left, const ErrorLogMap &right)
Definition: error-util.cc:159
void AppendError(ErrorLogMap *map, const ErrorMsg &e)
Definition: error-util.cc:177
string GetStrErrMsg()
Definition: error-util.cc:30
size_t ErrorCount(const ErrorLogMap &errors)
Definition: error-util.cc:191
static ErrorMsg Init(TErrorCode::type error, const ArgType &arg0=ArgType::NoArg, const ArgType &arg1=ArgType::NoArg, const ArgType &arg2=ArgType::NoArg, const ArgType &arg3=ArgType::NoArg, const ArgType &arg4=ArgType::NoArg, const ArgType &arg5=ArgType::NoArg, const ArgType &arg6=ArgType::NoArg, const ArgType &arg7=ArgType::NoArg, const ArgType &arg8=ArgType::NoArg, const ArgType &arg9=ArgType::NoArg)
Definition: error-util.cc:122
strings::internal::SubstituteArg ArgType
Definition: error-util.h:49
void PrintErrorMap(ostream *stream, const ErrorLogMap &errors)
Definition: error-util.cc:136
std::string message_
Definition: error-util.h:139
ErrorMsg()
Trivial constructor.
Definition: error-util.h:52
std::map< TErrorCode::type, TErrorLogEntry > ErrorLogMap
Tracks log messages per error code.
Definition: error-util.h:144