Add system.errors table

Contains error codes with number of times they have been triggered.

Columns:

-   `name` ([String](../../sql-reference/data-types/string.md)) — name of the error (`errorCodeToName`).
-   `code` ([Int32](../../sql-reference/data-types/int-uint.md)) — code number of the error.
-   `value` ([UInt64](../../sql-reference/data-types/int-uint.md)) - number of times this error has been happened.

**Example**

``` sql
SELECT *
FROM system.errors
WHERE value > 0
ORDER BY code ASC
LIMIT 1

┌─name─────────────┬─code─┬─value─┐
│ CANNOT_OPEN_FILE │   76 │     1 │
└──────────────────┴──────┴───────┘
This commit is contained in:
Azat Khuzhin 2020-10-29 01:00:04 +03:00
parent 3fb8d08dd4
commit b2e2322895
13 changed files with 170 additions and 21 deletions

View File

@ -277,6 +277,8 @@ TESTS_TO_SKIP=(
# Require python libraries like scipy, pandas and numpy
01322_ttest_scipy
01545_system_errors
)
time clickhouse-test -j 8 --order=random --no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee "$FASTTEST_OUTPUT/test_log.txt"

View File

@ -0,0 +1,23 @@
# system.errors {#system_tables-errors}
Contains error codes with number of times they have been triggered.
Columns:
- `name` ([String](../../sql-reference/data-types/string.md)) — name of the error (`errorCodeToName`).
- `code` ([Int32](../../sql-reference/data-types/int-uint.md)) — code number of the error.
- `value` ([UInt64](../../sql-reference/data-types/int-uint.md)) - number of times this error has been happened.
**Example**
``` sql
SELECT *
FROM system.errors
WHERE value > 0
ORDER BY code ASC
LIMIT 1
┌─name─────────────┬─code─┬─value─┐
│ CANNOT_OPEN_FILE │ 76 │ 1 │
└──────────────────┴──────┴───────┘
```

View File

@ -86,6 +86,21 @@ endif()
list (APPEND clickhouse_common_io_sources ${CONFIG_BUILD})
list (APPEND clickhouse_common_io_headers ${CONFIG_VERSION} ${CONFIG_COMMON})
# ErrorCodes
set(ERROR_CODES_IN ${CMAKE_CURRENT_SOURCE_DIR}/Common/ErrorCodes.cpp)
set(ERROR_CODES_OUT ${CMAKE_CURRENT_BINARY_DIR}/Common/errorCodes.generated.cpp)
add_custom_target(generate-error-codes
env
ERROR_CODES_IN_FILE=${ERROR_CODES_IN}
ERROR_CODES_OUT_FILE=${ERROR_CODES_OUT}
CXX=${CMAKE_CXX_COMPILER}
${CMAKE_CURRENT_SOURCE_DIR}/Common/errorCodes.sh
SOURCES Common/errorCodes.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
BYPRODUCTS ${ERROR_CODES_OUT}
)
list(APPEND clickhouse_common_io_sources ${ERROR_CODES_OUT})
list (APPEND dbms_sources Functions/IFunction.cpp Functions/FunctionFactory.cpp Functions/FunctionHelpers.cpp Functions/extractTimeZoneFromFunctionArguments.cpp)
list (APPEND dbms_headers Functions/IFunctionImpl.h Functions/FunctionFactory.h Functions/FunctionHelpers.h Functions/extractTimeZoneFromFunctionArguments.h)

View File

@ -12,14 +12,19 @@
#include <IO/ReadBufferFromFile.h>
#include <common/demangle.h>
#include <common/errnoToString.h>
#include <Interpreters/AggregationCommon.h>
#include <Common/formatReadable.h>
#include <Common/filesystemHelpers.h>
#include <Common/HashTable/HashMap.h>
#include <filesystem>
#include <atomic>
#if !defined(ARCADIA_BUILD)
# include <Common/config_version.h>
#endif
extern HashMap<int, std::atomic<uint64_t>, DefaultHash<int>> error_codes_count;
namespace DB
{
@ -45,6 +50,7 @@ Exception::Exception(const std::string & msg, int code)
LOG_FATAL(&Poco::Logger::root(), "Logical error: '{}'.", msg);
abort();
}
++error_codes_count[code];
#endif
}

View File

@ -17,20 +17,26 @@ CXX=${CXX=g++}
trap 'rm -f $TMP_FILE' EXIT
TMP_FILE="$(mktemp clichouse_generate_errorCodes_XXXXXXXX.cpp)"
function parse_for_errorCodeToName()
function parse_ErrorCodes()
{
# This is the simplest command that can be written to parse the file
# And it does not requires any extra tools and works everywhere where you have g++/clang++
#
# Generate:
#
# CODE VAR_NAME
#
$CXX -E "$ERROR_CODES_IN_FILE" | {
awk -F '[ =;]*' '/extern const int / { printf(" case %s: return std::string_view(\"%s\");\n", $(NF-1), $(NF-2)); }'
awk -F '[ =;]*' '/extern const int / { print $(NF-1), $(NF-2); }'
}
}
function parse_for_errorCodeToName()
{
parse_ErrorCodes | awk '{ printf(" case %s: return std::string_view(\"%s\");\n", $1, $2); }'
}
function generate_errorCodeToName()
{
cat <<EOL
// autogenerated by ${BASH_SOURCE[0]}
#include <string_view>
std::string_view errorCodeToName(int code)
@ -46,9 +52,35 @@ $(parse_for_errorCodeToName)
EOL
}
function parse_for_error_codes_count()
{
parse_ErrorCodes | awk '{ printf(" error_codes_count[%s] = 0; /* %s */\n", $1, $2); }'
}
function generate_error_codes_count()
{
cat <<EOL
#include <Common/HashTable/HashMap.h>
#include <Databases/IDatabase.h>
#include <Interpreters/AggregationCommon.h>
#include <atomic>
HashMap<int, std::atomic<uint64_t>, DefaultHash<int>> error_codes_count;
struct InitializeErrorCodesCount
{
InitializeErrorCodesCount()
{
$(parse_for_error_codes_count)
}
} error_codes_count_initialize;
EOL
}
function main()
{
generate_errorCodeToName > "$TMP_FILE"
echo "// autogenerated by ${BASH_SOURCE[0]}" > "$TMP_FILE"
generate_errorCodeToName >> "$TMP_FILE"
generate_error_codes_count >> "$TMP_FILE"
if [[ ! -e $ERROR_CODES_OUT_FILE ]]; then
cp -a "$TMP_FILE" "$ERROR_CODES_OUT_FILE"

View File

@ -23,7 +23,7 @@ INCLUDE(${ARCADIA_ROOT}/clickhouse/cmake/yandex/ya.make.versions.inc)
CFLAGS(-g0)
SRCS(
<? find . -name '*.cpp' | grep -v -F tests | sed 's/^\.\// /' | sort ?>
<? find . -name '*.cpp' | grep -v -F -e tests -e errorCodes | sed 's/^\.\// /' | sort ?>
)
END()

View File

@ -6,20 +6,6 @@ add_headers_and_sources(clickhouse_functions .)
list(REMOVE_ITEM clickhouse_functions_sources IFunctionImpl.cpp FunctionFactory.cpp FunctionHelpers.cpp)
list(REMOVE_ITEM clickhouse_functions_headers IFunctionImpl.h FunctionFactory.h FunctionHelpers.h)
set(ERROR_CODES_IN ${CMAKE_CURRENT_SOURCE_DIR}/../Common/ErrorCodes.cpp)
set(ERROR_CODES_OUT ${CMAKE_CURRENT_BINARY_DIR}/errorCodes.generated.cpp)
add_custom_target(generate-error-codes
env
ERROR_CODES_IN_FILE=${ERROR_CODES_IN}
ERROR_CODES_OUT_FILE=${ERROR_CODES_OUT}
CXX=${CMAKE_CXX_COMPILER}
${CMAKE_CURRENT_SOURCE_DIR}/errorCodes.sh
SOURCES errorCodes.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
BYPRODUCTS ${ERROR_CODES_OUT}
)
list(APPEND clickhouse_functions_sources ${ERROR_CODES_OUT})
if (NOT USE_H3)
list (REMOVE_ITEM clickhouse_functions_sources
geoToH3.cpp

View File

@ -0,0 +1,43 @@
#include <Columns/ColumnString.h>
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeString.h>
#include <DataTypes/DataTypesNumber.h>
#include <Storages/System/StorageSystemErrors.h>
#include <Storages/Distributed/DirectoryMonitor.h>
#include <Storages/StorageDistributed.h>
#include <Storages/VirtualColumnUtils.h>
#include <Access/ContextAccess.h>
#include <Common/typeid_cast.h>
#include <Common/HashTable/HashMap.h>
#include <Databases/IDatabase.h>
#include <Interpreters/AggregationCommon.h>
#include <atomic>
extern std::string_view errorCodeToName(int code);
extern HashMap<int, std::atomic<uint64_t>, DefaultHash<int>> error_codes_count;
namespace DB
{
NamesAndTypesList StorageSystemErrors::getNamesAndTypes()
{
return {
{ "name", std::make_shared<DataTypeString>() },
{ "code", std::make_shared<DataTypeInt32>() },
{ "value", std::make_shared<DataTypeUInt64>() },
};
}
void StorageSystemErrors::fillData(MutableColumns & res_columns, const Context &, const SelectQueryInfo &) const
{
for (const auto & error_code_pair : error_codes_count)
{
size_t col_num = 0;
res_columns[col_num++]->insert(errorCodeToName(error_code_pair.getKey()));
res_columns[col_num++]->insert(error_code_pair.getKey());
res_columns[col_num++]->insert(uint64_t(error_code_pair.getMapped()));
}
}
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <ext/shared_ptr_helper.h>
#include <Storages/System/IStorageSystemOneBlock.h>
namespace DB
{
class Context;
/** Implements the `distribution_queue` system table, which allows you to view the INSERT queues for the Distributed tables.
*/
class StorageSystemErrors final : public ext::shared_ptr_helper<StorageSystemErrors>, public IStorageSystemOneBlock<StorageSystemErrors>
{
friend struct ext::shared_ptr_helper<StorageSystemErrors>;
public:
std::string getName() const override { return "SystemErrors"; }
static NamesAndTypesList getNamesAndTypes();
protected:
using IStorageSystemOneBlock::IStorageSystemOneBlock;
void fillData(MutableColumns & res_columns, const Context &, const SelectQueryInfo &) const override;
};
}

View File

@ -41,6 +41,7 @@
#include <Storages/System/StorageSystemLicenses.h>
#include <Storages/System/StorageSystemTimeZones.h>
#endif
#include <Storages/System/StorageSystemErrors.h>
#include <Storages/System/StorageSystemDisks.h>
#include <Storages/System/StorageSystemStoragePolicies.h>
#include <Storages/System/StorageSystemZeros.h>
@ -110,6 +111,7 @@ void attachSystemTablesLocal(IDatabase & system_database)
#if !defined(ARCADIA_BUILD)
attach<StorageSystemLicenses>(system_database, "licenses");
attach<StorageSystemTimeZones>(system_database, "time_zones");
attach<StorageSystemErrors>(system_database, "errors");
#endif
#ifdef OS_LINUX
attach<StorageSystemStackTrace>(system_database, "stack_trace");

View File

@ -154,6 +154,7 @@ SRCS(
System/StorageSystemDisks.cpp
System/StorageSystemDistributionQueue.cpp
System/StorageSystemEnabledRoles.cpp
System/StorageSystemErrors.cpp
System/StorageSystemEvents.cpp
System/StorageSystemFormats.cpp
System/StorageSystemFunctions.cpp

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
. "$CURDIR"/../shell_config.sh
prev="$(${CLICKHOUSE_CLIENT} -q "SELECT value FROM system.errors WHERE name = 'FUNCTION_THROW_IF_VALUE_IS_NON_ZERO'")"
$CLICKHOUSE_CLIENT -q 'SELECT throwIf(1)' >& /dev/null
cur="$(${CLICKHOUSE_CLIENT} -q "SELECT value FROM system.errors WHERE name = 'FUNCTION_THROW_IF_VALUE_IS_NON_ZERO'")"
echo $((cur - prev))