// Modifications copyright (C) 2017, Baidu.com, Inc. // Copyright 2017 The Apache Software Foundation // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. #include "util/debug_util.h" #include "common/logging.h" #include #include #include "common/logging.h" #include "gen_cpp/version.h" #include "runtime/descriptors.h" #include "runtime/raw_value.h" #include "runtime/tuple_row.h" #include "runtime/row_batch.h" #include "util/cpu_info.h" #include "gen_cpp/Opcodes_types.h" #define PRECISION 2 #define KILOBYTE (1024) #define MEGABYTE (1024 * 1024) #define GIGABYTE (1024 * 1024 * 1024) #define SECOND (1000) #define MINUTE (1000 * 60) #define HOUR (1000 * 60 * 60) #define THOUSAND (1000) #define MILLION (THOUSAND * 1000) #define BILLION (MILLION * 1000) namespace google { namespace glog_internal_namespace_ { void DumpStackTraceToString(std::string* stacktrace); } } namespace palo { #define THRIFT_ENUM_OUTPUT_FN_IMPL(E, MAP) \ std::ostream& operator<<(std::ostream& os, const E::type& e) {\ std::map::const_iterator i;\ i = MAP.find(e);\ if (i != MAP.end()) {\ os << i->second;\ }\ return os;\ } // Macro to stamp out operator<< for thrift enums. Why doesn't thrift do this? #define THRIFT_ENUM_OUTPUT_FN(E) THRIFT_ENUM_OUTPUT_FN_IMPL(E, _##E##_VALUES_TO_NAMES) // Macro to implement Print function that returns string for thrift enums #define THRIFT_ENUM_PRINT_FN(E) \ std::string Print##E(const E::type& e) {\ std::stringstream ss;\ ss << e;\ return ss.str();\ } THRIFT_ENUM_OUTPUT_FN(TExprOpcode); THRIFT_ENUM_OUTPUT_FN(TAggregationOp); THRIFT_ENUM_OUTPUT_FN(THdfsFileFormat); THRIFT_ENUM_OUTPUT_FN(THdfsCompression); THRIFT_ENUM_OUTPUT_FN(TStmtType); THRIFT_ENUM_OUTPUT_FN(QueryState); THRIFT_ENUM_OUTPUT_FN(TAgentServiceVersion); THRIFT_ENUM_PRINT_FN(TStmtType); THRIFT_ENUM_PRINT_FN(QueryState); THRIFT_ENUM_PRINT_FN(TMetricKind); THRIFT_ENUM_PRINT_FN(TUnit); std::string print_id(const TUniqueId& id) { std::stringstream out; out << std::hex << id.hi << ":" << id.lo; return out.str(); } bool parse_id(const std::string& s, TUniqueId* id) { DCHECK(id != NULL); const char* hi_part = s.c_str(); char* colon = const_cast(strchr(hi_part, ':')); if (colon == NULL) { return false; } const char* lo_part = colon + 1; *colon = '\0'; char* error_hi = NULL; char* error_lo = NULL; id->hi = strtoul(hi_part, &error_hi, 16); id->lo = strtoul(lo_part, &error_lo, 16); bool valid = *error_hi == '\0' && *error_lo == '\0'; *colon = ':'; return valid; } std::string print_plan_node_type(const TPlanNodeType::type& type) { std::map::const_iterator i; i = _TPlanNodeType_VALUES_TO_NAMES.find(type); if (i != _TPlanNodeType_VALUES_TO_NAMES.end()) { return i->second; } return "Invalid plan node type"; } std::string print_tuple(const Tuple* t, const TupleDescriptor& d) { if (t == NULL) { return "null"; } std::stringstream out; out << "("; bool first_value = true; for (int i = 0; i < d.slots().size(); ++i) { SlotDescriptor* slot_d = d.slots()[i]; if (!slot_d->is_materialized()) { continue; } if (first_value) { first_value = false; } else { out << " "; } if (t->is_null(slot_d->null_indicator_offset())) { out << "null"; } else { std::string value_str; RawValue::print_value( t->get_slot(slot_d->tuple_offset()), slot_d->type(), -1, &value_str); out << value_str; } } out << ")"; return out.str(); } std::string print_row(TupleRow* row, const RowDescriptor& d) { std::stringstream out; out << "["; for (int i = 0; i < d.tuple_descriptors().size(); ++i) { if (i != 0) { out << " "; } out << print_tuple(row->get_tuple(i), *d.tuple_descriptors()[i]); } out << "]"; return out.str(); } std::string print_batch(RowBatch* batch) { std::stringstream out; for (int i = 0; i < batch->num_rows(); ++i) { out << print_row(batch->get_row(i), batch->row_desc()) << "\n"; } return out.str(); } std::string get_build_version(bool compact) { std::stringstream ss; ss << PALO_BUILD_VERSION #ifdef NDEBUG << " RELEASE" #else << " DEBUG" #endif << " (build " << PALO_BUILD_HASH << ")"; if (!compact) { ss << std::endl << "Built on " << PALO_BUILD_TIME << " by " << PALO_BUILD_INFO; } return ss.str(); } std::string get_version_string(bool compact) { std::stringstream ss; ss << " version " << get_build_version(compact); return ss.str(); } std::string get_stack_trace() { std::string s; google::glog_internal_namespace_::DumpStackTraceToString(&s); return s; } }