Merge pull request #33134 from ClickHouse/musl-check-2

Prepare ClickHouse to be built with musl-libc
This commit is contained in:
alexey-milovidov 2021-12-24 19:44:47 +03:00 committed by GitHub
commit 888a5532a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
107 changed files with 510 additions and 512 deletions

View File

@ -424,6 +424,11 @@ if (OS_LINUX AND NOT SANITIZE)
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
endif ()
# Increase stack size on Musl. We need big stack for our recursive-descend parser.
if (USE_MUSL)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,stack-size=2097152")
endif ()
include(cmake/dbms_glob_sources.cmake)
if (OS_LINUX OR OS_ANDROID)

View File

@ -9,7 +9,3 @@ add_subdirectory (pcg-random)
add_subdirectory (widechar_width)
add_subdirectory (readpassphrase)
add_subdirectory (bridge)
if (USE_MYSQL)
add_subdirectory (mysqlxx)
endif ()

View File

@ -1,8 +1,6 @@
set (SRCS
argsToConfig.cpp
coverage.cpp
DateLUT.cpp
DateLUTImpl.cpp
demangle.cpp
getFQDNOrHostName.cpp
getMemoryAmount.cpp
@ -18,7 +16,6 @@ set (SRCS
sleep.cpp
terminalColors.cpp
errnoToString.cpp
getResource.cpp
StringRef.cpp
)

View File

@ -123,6 +123,12 @@ bool hasPHDRCache()
#else
void updatePHDRCache() {}
bool hasPHDRCache() { return false; }
#if defined(USE_MUSL)
/// With statically linked with musl, dl_iterate_phdr is immutable.
bool hasPHDRCache() { return true; }
#else
bool hasPHDRCache() { return false; }
#endif
#endif

View File

@ -1,61 +0,0 @@
add_library (mysqlxx
Connection.cpp
Exception.cpp
Query.cpp
ResultBase.cpp
UseQueryResult.cpp
Row.cpp
Value.cpp
Pool.cpp
PoolFactory.cpp
PoolWithFailover.cpp
)
target_include_directories (mysqlxx PUBLIC ..)
if (NOT USE_INTERNAL_MYSQL_LIBRARY)
set(PLATFORM_LIBRARIES ${CMAKE_DL_LIBS})
if (USE_MYSQL)
target_include_directories (mysqlxx SYSTEM PRIVATE ${MYSQL_INCLUDE_DIR})
endif ()
if (APPLE)
find_library (ICONV_LIBRARY iconv)
set (MYSQLCLIENT_LIBRARIES ${MYSQLCLIENT_LIBRARIES} ${STATIC_MYSQLCLIENT_LIB} ${ICONV_LIBRARY})
elseif (USE_STATIC_LIBRARIES AND STATIC_MYSQLCLIENT_LIB)
set (MYSQLCLIENT_LIBRARIES ${STATIC_MYSQLCLIENT_LIB})
endif ()
endif ()
target_link_libraries (mysqlxx
PUBLIC
common
PRIVATE
${MYSQLCLIENT_LIBRARIES}
${ZLIB_LIBRARIES}
)
if(OPENSSL_LIBRARIES)
target_link_libraries(mysqlxx PRIVATE ${OPENSSL_LIBRARIES})
endif()
target_link_libraries(mysqlxx PRIVATE ${PLATFORM_LIBRARIES})
if (NOT USE_INTERNAL_MYSQL_LIBRARY AND OPENSSL_INCLUDE_DIR)
target_include_directories (mysqlxx SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR})
endif ()
target_no_warning(mysqlxx reserved-macro-identifier)
if (NOT USE_INTERNAL_MYSQL_LIBRARY AND USE_STATIC_LIBRARIES)
message(WARNING "Statically linking with system mysql/mariadb only works "
"if mysql client libraries are built with same openssl version as "
"we are going to use now. It wouldn't work if GnuTLS is used. "
"Try -D\"USE_INTERNAL_MYSQL_LIBRARY\"=ON or -D\"ENABLE_MYSQL\"=OFF or "
"-D\"USE_STATIC_LIBRARIES\"=OFF")
endif ()
if (ENABLE_TESTS)
add_subdirectory (tests)
endif ()

View File

@ -42,6 +42,14 @@ if (CMAKE_CROSSCOMPILING)
message (FATAL_ERROR "Trying to cross-compile to unsupported system: ${CMAKE_SYSTEM_NAME}!")
endif ()
if (USE_MUSL)
set (USE_SENTRY OFF CACHE INTERNAL "")
set (ENABLE_ODBC OFF CACHE INTERNAL "")
set (ENABLE_GRPC OFF CACHE INTERNAL "")
set (ENABLE_HDFS OFF CACHE INTERNAL "")
set (ENABLE_EMBEDDED_COMPILER OFF CACHE INTERNAL "")
endif ()
# Don't know why but CXX_STANDARD doesn't work for cross-compilation
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")

View File

@ -446,7 +446,7 @@ set (HAVE_STRERROR_R 1)
set (HAVE_SCHED_GET_PRIORITY_MAX 1)
set (HAVE_SCHED_GET_PRIORITY_MIN 1)
if (OS_LINUX)
if (OS_LINUX AND NOT USE_MUSL)
set (STRERROR_R_CHAR_P 1)
endif ()

View File

@ -1,17 +1,8 @@
# This file is a modified version of contrib/libuv/CMakeLists.txt
include(CMakeDependentOption)
set (SOURCE_DIR "${CMAKE_SOURCE_DIR}/contrib/libuv")
set (BINARY_DIR "${CMAKE_BINARY_DIR}/contrib/libuv")
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU")
list(APPEND uv_cflags -fvisibility=hidden --std=gnu89)
list(APPEND uv_cflags -Wall -Wextra -Wstrict-prototypes)
list(APPEND uv_cflags -Wno-unused-parameter)
endif()
set(uv_sources
src/fs-poll.c
src/idna.c
@ -76,7 +67,7 @@ endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND uv_defines _GNU_SOURCE _POSIX_C_SOURCE=200112)
list(APPEND uv_libraries dl rt)
list(APPEND uv_libraries rt)
list(APPEND uv_sources
src/unix/linux-core.c
src/unix/linux-inotify.c

View File

@ -236,8 +236,7 @@ set(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} ${CC_SOURCE_DIR}/libmariadb/mariadb
add_library(mariadbclient STATIC ${LIBMARIADB_SOURCES})
target_link_libraries(mariadbclient ${SYSTEM_LIBS})
target_include_directories(mariadbclient
PRIVATE ${CC_BINARY_DIR}/include-private
PUBLIC ${CC_BINARY_DIR}/include-public ${CC_SOURCE_DIR}/include ${CC_SOURCE_DIR}/libmariadb)
target_include_directories(mariadbclient PRIVATE ${CC_BINARY_DIR}/include-private)
target_include_directories(mariadbclient SYSTEM PUBLIC ${CC_BINARY_DIR}/include-public ${CC_SOURCE_DIR}/include ${CC_SOURCE_DIR}/libmariadb)
set_target_properties(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")

View File

@ -20,7 +20,7 @@
#include <Common/Config/ConfigProcessor.h>
#include <Common/OpenSSLHelpers.h>
#include <Common/hex.h>
#include <base/getResource.h>
#include <Common/getResource.h>
#include <base/sleep.h>
#include <IO/ReadBufferFromFileDescriptor.h>
#include <IO/WriteBufferFromFileDescriptor.h>

View File

@ -30,7 +30,7 @@
#include <Processors/Executors/PushingPipelineExecutor.h>
#include <Core/Block.h>
#include <base/StringRef.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <base/bit_cast.h>
#include <IO/ReadBufferFromFileDescriptor.h>
#include <IO/WriteBufferFromFileDescriptor.h>

View File

@ -1,13 +1,8 @@
#include "ODBCBlockOutputStream.h"
#include <Common/hex.h>
#include <base/logger_useful.h>
#include <Core/Field.h>
#include <base/LocalDate.h>
#include <base/LocalDateTime.h>
#include "getIdentifierQuote.h"
#include <IO/WriteHelpers.h>
#include <IO/Operators.h>
#include <IO/WriteBufferFromString.h>
#include <Interpreters/Context.h>
#include <Processors/Formats/IOutputFormat.h>
#include <Parsers/getInsertQuery.h>
@ -45,7 +40,7 @@ void ODBCSink::consume(Chunk chunk)
std::string query = getInsertQuery(db_name, table_name, block.getColumnsWithTypeAndName(), quoting) + values_buf.str();
execute<void>(connection_holder,
[&](nanodbc::connection & connection) { execute(connection, query); });
[&](nanodbc::connection & connection) { execute(connection, query); });
}
}

View File

@ -8,8 +8,8 @@
#include <unordered_map>
#include <base/argsToConfig.h>
#include <base/DateLUT.h>
#include <base/LocalDate.h>
#include <Common/DateLUT.h>
#include <Common/LocalDate.h>
#include <base/LineReader.h>
#include <base/scope_guard_safe.h>
#include "Common/Exception.h"

View File

@ -1,8 +1,8 @@
#include "ClientBaseHelpers.h"
#include <base/DateLUT.h>
#include <base/LocalDate.h>
#include <Common/DateLUT.h>
#include <Common/LocalDate.h>
#include <Parsers/Lexer.h>
#include <Common/UTF8Helpers.h>

View File

@ -1,8 +1,9 @@
add_subdirectory(StringUtils)
# after common_io
#add_subdirectory(ZooKeeper)
#add_subdirectory(ConfigProcessor)
if (ENABLE_EXAMPLES)
add_subdirectory(examples)
endif()
if (USE_MYSQL)
add_subdirectory (mysqlxx)
endif ()

View File

@ -18,7 +18,7 @@
#include <Common/ZooKeeper/KeeperException.h>
#include <Common/StringUtils/StringUtils.h>
#include <Common/Exception.h>
#include <base/getResource.h>
#include <Common/getResource.h>
#include <base/errnoToString.h>
#include <IO/WriteBufferFromString.h>
#include <IO/Operators.h>

View File

@ -2,7 +2,7 @@
#include "DateLUTImpl.h"
#include "defines.h"
#include <base/defines.h>
#include <boost/noncopyable.hpp>

View File

@ -3,7 +3,7 @@
#include <cctz/civil_time.h>
#include <cctz/time_zone.h>
#include <cctz/zone_info_source.h>
#include <base/getResource.h>
#include <Common/getResource.h>
#include <Poco/Exception.h>
#include <algorithm>

View File

@ -1,8 +1,8 @@
#pragma once
#include "DayNum.h"
#include "defines.h"
#include "types.h"
#include <base/DayNum.h>
#include <base/defines.h>
#include <base/types.h>
#include <ctime>
#include <cassert>

View File

@ -2,9 +2,8 @@
#include <string.h>
#include <string>
#include <sstream>
#include <exception>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
/** Stores a calendar date in broken-down form (year, month, day-in-month).
@ -154,19 +153,6 @@ public:
{
return !(*this == other);
}
/// NOTE Inefficient.
std::string toString(char separator = '-') const
{
std::stringstream ss;
if (separator)
ss << year() << separator << (month() / 10) << (month() % 10)
<< separator << (day() / 10) << (day() % 10);
else
ss << year() << (month() / 10) << (month() % 10)
<< (day() / 10) << (day() % 10);
return ss.str();
}
};
static_assert(sizeof(LocalDate) == 4);

View File

@ -3,8 +3,8 @@
#include <string>
#include <iomanip>
#include <exception>
#include <base/DateLUT.h>
#include <base/LocalDate.h>
#include <Common/DateLUT.h>
#include <Common/LocalDate.h>
/** Stores calendar date and time in broken-down form.

View File

@ -155,12 +155,17 @@ std::unique_ptr<ShellCommand> ShellCommand::executeImpl(
{
logCommand(filename, argv);
#if !defined(USE_MUSL)
/** Here it is written that with a normal call `vfork`, there is a chance of deadlock in multithreaded programs,
* because of the resolving of symbols in the shared library
* http://www.oracle.com/technetwork/server-storage/solaris10/subprocess-136439.html
* Therefore, separate the resolving of the symbol from the call.
*/
static void * real_vfork = dlsym(RTLD_DEFAULT, "vfork");
#else
/// If we use Musl with static linking, there is no dlsym and no issue with vfork.
static void * real_vfork = reinterpret_cast<void *>(&vfork);
#endif
if (!real_vfork)
throwFromErrno("Cannot find symbol vfork in myself", ErrorCodes::CANNOT_DLSYM);

View File

@ -7,7 +7,7 @@
#include <base/logger_useful.h>
#include <base/errnoToString.h>
#include <Common/ClickHouseRevision.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
#include <IO/ReadBufferFromFile.h>
#include <IO/LimitReadBuffer.h>

View File

@ -5,6 +5,7 @@
#include <algorithm>
#include <optional>
#include <cassert>
#include <link.h>
@ -85,12 +86,43 @@ namespace
/// https://stackoverflow.com/questions/32088140/multiple-string-tables-in-elf-object
void updateResources(std::string_view name, const void * address, SymbolIndex::Resources & resources)
{
const char * char_address = static_cast<const char *>(address);
if (name.starts_with("_binary_") || name.starts_with("binary_"))
{
if (name.ends_with("_start"))
{
name = name.substr((name[0] == '_') + strlen("binary_"));
name = name.substr(0, name.size() - strlen("_start"));
resources.emplace(name, std::string_view{char_address, 0}); // NOLINT
}
else if (name.ends_with("_end"))
{
name = name.substr((name[0] == '_') + strlen("binary_"));
name = name.substr(0, name.size() - strlen("_end"));
if (auto it = resources.find(name); it != resources.end() && it->second.empty())
{
const char * start = it->second.data();
assert(char_address >= start);
it->second = std::string_view{start, static_cast<size_t>(char_address - start)};
}
}
}
}
/// Based on the code of musl-libc and the answer of Kanalpiroge on
/// https://stackoverflow.com/questions/15779185/list-all-the-functions-symbols-on-the-fly-in-c-code-on-a-linux-architecture
/// It does not extract all the symbols (but only public - exported and used for dynamic linking),
/// but will work if we cannot find or parse ELF files.
void collectSymbolsFromProgramHeaders(dl_phdr_info * info,
std::vector<SymbolIndex::Symbol> & symbols)
void collectSymbolsFromProgramHeaders(
dl_phdr_info * info,
std::vector<SymbolIndex::Symbol> & symbols,
SymbolIndex::Resources & resources)
{
/* Iterate over all headers of the current shared lib
* (first call is for the executable itself)
@ -184,10 +216,6 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info,
/* Iterate over the symbol table */
for (ElfW(Word) sym_index = 0; sym_index < ElfW(Word)(sym_cnt); ++sym_index)
{
/// We are not interested in empty symbols.
if (!elf_sym[sym_index].st_size)
continue;
/* Get the name of the sym_index-th symbol.
* This is located at the address of st_name relative to the beginning of the string table.
*/
@ -197,10 +225,18 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info,
continue;
SymbolIndex::Symbol symbol;
symbol.address_begin = reinterpret_cast<const void *>(info->dlpi_addr + elf_sym[sym_index].st_value);
symbol.address_end = reinterpret_cast<const void *>(info->dlpi_addr + elf_sym[sym_index].st_value + elf_sym[sym_index].st_size);
symbol.address_begin = reinterpret_cast<const void *>(
info->dlpi_addr + elf_sym[sym_index].st_value);
symbol.address_end = reinterpret_cast<const void *>(
info->dlpi_addr + elf_sym[sym_index].st_value + elf_sym[sym_index].st_size);
symbol.name = sym_name;
symbols.push_back(symbol);
/// We are not interested in empty symbols.
if (elf_sym[sym_index].st_size)
symbols.push_back(symbol);
/// But resources can be represented by a pair of empty symbols (indicating their boundaries).
updateResources(symbol.name, symbol.address_begin, resources);
}
break;
@ -210,6 +246,7 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info,
}
#if !defined USE_MUSL
String getBuildIDFromProgramHeaders(dl_phdr_info * info)
{
for (size_t header_index = 0; header_index < info->dlpi_phnum; ++header_index)
@ -222,6 +259,7 @@ String getBuildIDFromProgramHeaders(dl_phdr_info * info)
}
return {};
}
#endif
void collectSymbolsFromELFSymbolTable(
@ -229,7 +267,8 @@ void collectSymbolsFromELFSymbolTable(
const Elf & elf,
const Elf::Section & symbol_table,
const Elf::Section & string_table,
std::vector<SymbolIndex::Symbol> & symbols)
std::vector<SymbolIndex::Symbol> & symbols,
SymbolIndex::Resources & resources)
{
/// Iterate symbol table.
const ElfSym * symbol_table_entry = reinterpret_cast<const ElfSym *>(symbol_table.begin());
@ -241,7 +280,6 @@ void collectSymbolsFromELFSymbolTable(
{
if (!symbol_table_entry->st_name
|| !symbol_table_entry->st_value
|| !symbol_table_entry->st_size
|| strings + symbol_table_entry->st_name >= elf.end())
continue;
@ -252,10 +290,16 @@ void collectSymbolsFromELFSymbolTable(
continue;
SymbolIndex::Symbol symbol;
symbol.address_begin = reinterpret_cast<const void *>(info->dlpi_addr + symbol_table_entry->st_value);
symbol.address_end = reinterpret_cast<const void *>(info->dlpi_addr + symbol_table_entry->st_value + symbol_table_entry->st_size);
symbol.address_begin = reinterpret_cast<const void *>(
info->dlpi_addr + symbol_table_entry->st_value);
symbol.address_end = reinterpret_cast<const void *>(
info->dlpi_addr + symbol_table_entry->st_value + symbol_table_entry->st_size);
symbol.name = symbol_name;
symbols.push_back(symbol);
if (symbol_table_entry->st_size)
symbols.push_back(symbol);
updateResources(symbol.name, symbol.address_begin, resources);
}
}
@ -265,7 +309,8 @@ bool searchAndCollectSymbolsFromELFSymbolTable(
const Elf & elf,
unsigned section_header_type,
const char * string_table_name,
std::vector<SymbolIndex::Symbol> & symbols)
std::vector<SymbolIndex::Symbol> & symbols,
SymbolIndex::Resources & resources)
{
std::optional<Elf::Section> symbol_table;
std::optional<Elf::Section> string_table;
@ -283,31 +328,45 @@ bool searchAndCollectSymbolsFromELFSymbolTable(
return false;
}
collectSymbolsFromELFSymbolTable(info, elf, *symbol_table, *string_table, symbols);
collectSymbolsFromELFSymbolTable(info, elf, *symbol_table, *string_table, symbols, resources);
return true;
}
void collectSymbolsFromELF(dl_phdr_info * info,
void collectSymbolsFromELF(
dl_phdr_info * info,
std::vector<SymbolIndex::Symbol> & symbols,
std::vector<SymbolIndex::Object> & objects,
SymbolIndex::Resources & resources,
String & build_id)
{
String object_name;
String our_build_id;
#if defined (USE_MUSL)
object_name = "/proc/self/exe";
our_build_id = Elf(object_name).getBuildID();
build_id = our_build_id;
#else
/// MSan does not know that the program segments in memory are initialized.
__msan_unpoison_string(info->dlpi_name);
std::string object_name = info->dlpi_name;
String our_build_id = getBuildIDFromProgramHeaders(info);
object_name = info->dlpi_name;
our_build_id = getBuildIDFromProgramHeaders(info);
/// If the name is empty and there is a non-empty build-id - it's main executable.
/// Find a elf file for the main executable and set the build-id.
if (object_name.empty())
{
object_name = "/proc/self/exe";
if (our_build_id.empty())
our_build_id = Elf(object_name).getBuildID();
if (build_id.empty())
build_id = our_build_id;
}
#endif
std::error_code ec;
std::filesystem::path canonical_path = std::filesystem::canonical(object_name, ec);
@ -377,10 +436,12 @@ void collectSymbolsFromELF(dl_phdr_info * info,
object.name = object_name;
objects.push_back(std::move(object));
searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_SYMTAB, ".strtab", symbols);
searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_SYMTAB, ".strtab", symbols, resources);
/// Unneeded because they were parsed from "program headers" of loaded objects.
//searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_DYNSYM, ".dynstr", symbols);
/// Unneeded if they were parsed from "program headers" of loaded objects.
#if defined USE_MUSL
searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_DYNSYM, ".dynstr", symbols, resources);
#endif
}
@ -392,8 +453,8 @@ int collectSymbols(dl_phdr_info * info, size_t, void * data_ptr)
{
SymbolIndex::Data & data = *reinterpret_cast<SymbolIndex::Data *>(data_ptr);
collectSymbolsFromProgramHeaders(info, data.symbols);
collectSymbolsFromELF(info, data.symbols, data.objects, data.build_id);
collectSymbolsFromProgramHeaders(info, data.symbols, data.resources);
collectSymbolsFromELF(info, data.symbols, data.objects, data.resources, data.build_id);
/* Continue iterations */
return 0;
@ -424,7 +485,7 @@ const T * find(const void * address, const std::vector<T> & vec)
void SymbolIndex::update()
{
dl_iterate_phdr(collectSymbols, &data.symbols);
dl_iterate_phdr(collectSymbols, &data);
std::sort(data.objects.begin(), data.objects.end(), [](const Object & a, const Object & b) { return a.address_begin < b.address_begin; });
std::sort(data.symbols.begin(), data.symbols.end(), [](const Symbol & a, const Symbol & b) { return a.address_begin < b.address_begin; });

View File

@ -4,6 +4,7 @@
#include <vector>
#include <string>
#include <unordered_map>
#include <Common/Elf.h>
#include <boost/noncopyable.hpp>
@ -47,15 +48,27 @@ public:
const std::vector<Symbol> & symbols() const { return data.symbols; }
const std::vector<Object> & objects() const { return data.objects; }
std::string_view getResource(String name) const
{
if (auto it = data.resources.find(name); it != data.resources.end())
return it->second;
return {};
}
/// The BuildID that is generated by compiler.
String getBuildID() const { return data.build_id; }
String getBuildIDHex() const;
using Resources = std::unordered_map<std::string_view /* symbol name */, std::string_view /* blob */>;
struct Data
{
std::vector<Symbol> symbols;
std::vector<Object> objects;
String build_id;
/// Resources (embedded binary data) are located by symbols in form of _binary_name_start and _binary_name_end.
Resources resources;
};
private:
Data data;

View File

@ -1,8 +1,9 @@
#include "getResource.h"
#include "unaligned.h"
#include <dlfcn.h>
#include <string>
#include <boost/algorithm/string/replace.hpp>
#include <Common/SymbolIndex.h>
std::string_view getResource(std::string_view name)
{
@ -13,6 +14,11 @@ std::string_view getResource(std::string_view name)
std::replace(name_replaced.begin(), name_replaced.end(), '.', '_');
boost::replace_all(name_replaced, "+", "_PLUS_");
#if defined USE_MUSL
/// If static linking is used, we cannot use dlsym and have to parse ELF symbol table by ourself.
return DB::SymbolIndex::instance()->getResource(name_replaced);
#else
// In most `dlsym(3)` APIs, one passes the symbol name as it appears via
// something like `nm` or `objdump -t`. For example, a symbol `_foo` would be
// looked up with the string `"_foo"`.
@ -33,8 +39,8 @@ std::string_view getResource(std::string_view name)
std::string symbol_name_start = prefix + name_replaced + "_start";
std::string symbol_name_end = prefix + name_replaced + "_end";
const char* sym_start = reinterpret_cast<const char*>(dlsym(RTLD_DEFAULT, symbol_name_start.c_str()));
const char* sym_end = reinterpret_cast<const char*>(dlsym(RTLD_DEFAULT, symbol_name_end.c_str()));
const char * sym_start = reinterpret_cast<const char *>(dlsym(RTLD_DEFAULT, symbol_name_start.c_str()));
const char * sym_end = reinterpret_cast<const char *>(dlsym(RTLD_DEFAULT, symbol_name_end.c_str()));
if (sym_start && sym_end)
{
@ -42,4 +48,5 @@ std::string_view getResource(std::string_view name)
return { sym_start, resource_size };
}
return {};
#endif
}

View File

@ -0,0 +1,24 @@
add_library (mysqlxx
Connection.cpp
Exception.cpp
Query.cpp
ResultBase.cpp
UseQueryResult.cpp
Row.cpp
Value.cpp
Pool.cpp
PoolFactory.cpp
PoolWithFailover.cpp
)
target_include_directories (mysqlxx PUBLIC .)
target_link_libraries (mysqlxx
clickhouse_common_io
${MYSQLCLIENT_LIBRARIES}
${ZLIB_LIBRARIES}
)
if (ENABLE_TESTS)
add_subdirectory (tests)
endif ()

View File

@ -4,6 +4,7 @@
#include <mysql/mysql.h>
#endif
#include <mysqlxx/Exception.h>
#include <fmt/format.h>
namespace mysqlxx
@ -11,11 +12,7 @@ namespace mysqlxx
std::string errorMessage(MYSQL * driver)
{
std::stringstream res;
res << mysql_error(driver)
<< " (" << (driver->host ? driver->host : "(nullptr)")
<< ":" << driver->port << ")";
return res.str();
return fmt::format("{} ({}:{})", mysql_error(driver), driver->host ? driver->host : "(nullptr)", driver->port);
}
void checkError(MYSQL * driver)

View File

@ -3,13 +3,8 @@
#include <random>
#include <thread>
#include <mysqlxx/PoolWithFailover.h>
/// Duplicate of code from StringUtils.h. Copied here for less dependencies.
static bool startsWith(const std::string & s, const char * prefix)
{
return s.size() >= strlen(prefix) && 0 == memcmp(s.data(), prefix, strlen(prefix));
}
#include <IO/WriteBufferFromString.h>
#include <IO/Operators.h>
using namespace mysqlxx;
@ -31,7 +26,7 @@ PoolWithFailover::PoolWithFailover(
for (const auto & replica_config_key : replica_keys)
{
/// There could be another elements in the same level in configuration file, like "password", "port"...
if (startsWith(replica_config_key, "replica"))
if (replica_config_key.starts_with("replica"))
{
std::string replica_name = config_name_ + "." + replica_config_key;
@ -181,7 +176,7 @@ PoolWithFailover::Entry PoolWithFailover::get()
return (*full_pool)->get(wait_timeout);
}
std::stringstream message;
DB::WriteBufferFromOwnString message;
message << "Connections to all replicas failed: ";
for (auto it = replicas_by_priority.begin(); it != replicas_by_priority.end(); ++it)
for (auto jt = it->second.begin(); jt != it->second.end(); ++jt)

View File

@ -21,10 +21,7 @@ Query::Query(Connection * conn_, const std::string & query_string) : conn(conn_)
/// Важно в случае, если Query используется не из того же потока, что Connection.
mysql_thread_init();
if (!query_string.empty())
query_buf << query_string;
query_buf.imbue(std::locale::classic());
query = query_string;
}
Query::Query(const Query & other) : conn(other.conn)
@ -32,9 +29,7 @@ Query::Query(const Query & other) : conn(other.conn)
/// Важно в случае, если Query используется не из того же потока, что Connection.
mysql_thread_init();
query_buf.imbue(std::locale::classic());
*this << other.str();
query = other.query;
}
Query & Query::operator= (const Query & other)
@ -43,8 +38,7 @@ Query & Query::operator= (const Query & other)
return *this;
conn = other.conn;
query_buf.str(other.str());
query = other.query;
return *this;
}
@ -54,20 +48,13 @@ Query::~Query()
mysql_thread_end();
}
void Query::reset()
{
query_buf.str({});
}
void Query::executeImpl()
{
std::string query_string = query_buf.str();
MYSQL* mysql_driver = conn->getDriver();
auto & logger = Poco::Logger::get("mysqlxx::Query");
logger.trace("Running MySQL query using connection %lu", mysql_thread_id(mysql_driver));
if (mysql_real_query(mysql_driver, query_string.data(), query_string.size()))
if (mysql_real_query(mysql_driver, query.data(), query.size()))
{
const auto err_no = mysql_errno(mysql_driver);
switch (err_no)

View File

@ -156,19 +156,21 @@ void Value::throwException(const char * text) const
{
static constexpr size_t preview_length = 1000;
std::stringstream info;
info << text;
std::string info(text);
if (!isNull())
{
info << ": ";
info.write(m_data, m_length);
info.append(": ");
info.append(m_data, m_length);
}
if (res && res->getQuery())
info << ", query: " << res->getQuery()->str().substr(0, preview_length);
{
info.append(", query: ");
info.append(res->getQuery()->str().substr(0, preview_length));
}
throw CannotParseValue(info.str());
throw CannotParseValue(info);
}
}

View File

@ -154,7 +154,7 @@ public:
bool ping();
/// Creates query. It can be set with query string or later.
Query query(const std::string & str = "");
Query query(const std::string & str);
/// Get MySQL C API MYSQL object.
MYSQL * getDriver();

View File

@ -13,9 +13,7 @@ namespace mysqlxx
* Ссылается на Connection. Если уничтожить Connection, то Query станет некорректным и пользоваться им будет нельзя.
*
* Пример использования:
* mysqlxx::Query query = connection.query();
* query << "SELECT 1 AS x, 2 AS y, 3 AS z";
* query << " LIMIT 1";
* mysqlxx::Query query = connection.query("SELECT 1 AS x, 2 AS y, 3 AS z LIMIT 1");
* mysqlxx::UseQueryResult result = query.use();
*
* while (mysqlxx::Row row = result.fetch())
@ -29,14 +27,11 @@ namespace mysqlxx
class Query
{
public:
Query(Connection * conn_, const std::string & query_string = "");
Query(Connection * conn_, const std::string & query_string);
Query(const Query & other);
Query & operator= (const Query & other);
~Query();
/** Сбросить текст запроса. Это используется, если нужно написать новый запрос в том же объекте. */
void reset();
/** Выполнить запрос, результат которого не имеет значения (почти всё кроме SELECT). */
void execute();
@ -54,24 +49,12 @@ public:
/// Получить текст запроса (например, для вывода его в лог). См. ещё operator<< ниже.
std::string str() const
{
return query_buf.str();
}
auto rdbuf() const
{
return query_buf.rdbuf();
}
template <typename T>
inline Query & operator<< (T && x)
{
query_buf << std::forward<T>(x);
return *this;
return query;
}
private:
Connection * conn;
std::ostringstream query_buf;
std::string query;
void executeImpl();
};
@ -80,7 +63,7 @@ private:
/// Вывести текст запроса в ostream.
inline std::ostream & operator<< (std::ostream & ostr, const Query & query)
{
return ostr << query.rdbuf();
return ostr << query.str();
}

View File

@ -10,10 +10,10 @@
#include <base/preciseExp10.h>
#include <base/types.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <mysqlxx/Types.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
namespace mysqlxx

View File

@ -3,8 +3,8 @@
#include <mysqlxx/Connection.h>
#include <mysqlxx/Transaction.h>
#include <mysqlxx/Pool.h>
#include <base/LocalDate.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDate.h>
#include <Common/LocalDateTime.h>
#include <mysqlxx/Null.h>
@ -23,7 +23,7 @@
* where values are stored consecutively as (non-zero-terminated) strings.
*
* 2. Too slow methods for converting values to numbers.
* In mysql++, it is done through std::stringstream.
* In mysql++, it is done through std::s*****stream (it is banned in our codebase).
* This is slower than POSIX functions (strtoul, etc).
* In turn, this is slower than simple hand-coded functions,
* that doesn't respect locales and unused by MySQL number representations.

View File

@ -2,7 +2,6 @@
#include <chrono>
#include <iostream>
#include <sstream>
#include <thread>
@ -41,10 +40,7 @@ mysqlxx::Pool::Entry getWithFailover(mysqlxx::Pool & connections_pool)
std::this_thread::sleep_for(1s);
}
std::stringstream message;
message << "Connections to all replicas failed: " << connections_pool.getDescription();
throw Poco::Exception(message.str());
throw Poco::Exception("Connections to all replicas failed: " + connections_pool.getDescription());
}
}
@ -69,8 +65,7 @@ int main(int, char **)
std::clog << "Preparing query (5s sleep) ...";
std::this_thread::sleep_for(5s);
mysqlxx::Query query = worker->query();
query << test_query;
mysqlxx::Query query = worker->query(test_query);
std::clog << "ok" << std::endl;
std::clog << "Querying result (5s sleep) ...";

View File

@ -1,5 +1,5 @@
#include <base/DateLUT.h>
#include <base/DateLUTImpl.h>
#include <Common/DateLUT.h>
#include <Common/DateLUTImpl.h>
#include <gtest/gtest.h>

View File

@ -2,7 +2,7 @@
#include <stdexcept>
#include <gtest/gtest.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
void fillStackWithGarbage()

View File

@ -5,7 +5,7 @@
#include <IO/MySQLBinlogEventReadBuffer.h>
#include <IO/ReadHelpers.h>
#include <IO/Operators.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <Common/FieldVisitorToString.h>
#include <Core/MySQL/PacketsGeneric.h>
#include <Core/MySQL/PacketsProtocolText.h>

View File

@ -1,7 +1,7 @@
#pragma once
#include <DataTypes/DataTypeNumberBase.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
namespace DB
{

View File

@ -2,7 +2,7 @@
#include <Columns/ColumnVector.h>
#include <Common/assert_cast.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <Formats/FormatSettings.h>
#include <Formats/ProtobufReader.h>
#include <Formats/ProtobufWriter.h>

View File

@ -2,7 +2,7 @@
#include <Columns/ColumnVector.h>
#include <Common/assert_cast.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <Formats/FormatSettings.h>
#include <Formats/ProtobufReader.h>
#include <IO/ReadHelpers.h>

View File

@ -1,6 +1,6 @@
#pragma once
#include <Core/Types.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
class DateLUTImpl;

View File

@ -1,7 +1,7 @@
#include "ExecutableDictionarySource.h"
#include <base/logger_useful.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
#include <Common/ShellCommand.h>
#include <Processors/Sources/ShellCommandSource.h>

View File

@ -1,7 +1,7 @@
#include "ExecutablePoolDictionarySource.h"
#include <base/logger_useful.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
#include <Common/ShellCommand.h>
#include <Formats/formatBlock.h>

View File

@ -4,7 +4,7 @@
#include <IO/ReadWriteBufferFromHTTP.h>
#include <Poco/Net/HTTPBasicCredentials.h>
#include <Poco/URI.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
#include "DictionaryStructure.h"
#include "IDictionarySource.h"
#include <Interpreters/Context.h>

View File

@ -1,7 +1,7 @@
#pragma once
#include <Bridge/LibraryBridgeHelper.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
#include <Core/UUID.h>
#include "DictionaryStructure.h"
#include <Core/ExternalResultDescription.h>

View File

@ -101,7 +101,7 @@ void registerDictionarySourceMysql(DictionarySourceFactory & factory)
# include <DataTypes/DataTypeString.h>
# include <IO/WriteBufferFromString.h>
# include <IO/WriteHelpers.h>
# include <base/LocalDateTime.h>
# include <Common/LocalDateTime.h>
# include <base/logger_useful.h>
# include "readInvalidateQuery.h"
# include <mysqlxx/Exception.h>

View File

@ -5,7 +5,7 @@
#include "config_core.h"
#if USE_MYSQL
# include <base/LocalDateTime.h>
# include <Common/LocalDateTime.h>
# include <mysqlxx/PoolWithFailover.h>
# include "DictionaryStructure.h"
# include "ExternalQueryBuilder.h"

View File

@ -7,7 +7,7 @@
#if USE_LIBPQXX
#include "ExternalQueryBuilder.h"
#include <Core/Block.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
#include <base/logger_useful.h>
#include <Core/PostgreSQL/PoolWithFailover.h>

View File

@ -9,7 +9,7 @@
#include <Interpreters/Context.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Util/AbstractConfiguration.h>
#include <base/LocalDateTime.h>
#include <Common/LocalDateTime.h>
#include <base/logger_useful.h>
#include "DictionarySourceFactory.h"
#include "DictionaryStructure.h"

View File

@ -9,7 +9,7 @@
#include <Functions/extractTimeZoneFromFunctionArguments.h>
#include <Functions/IFunction.h>
#include <Common/Exception.h>
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
/// The default mode value to use for the WEEK() function
#define DEFAULT_WEEK_MODE 0

View File

@ -3,8 +3,8 @@
#include <base/types.h>
#include <Core/DecimalFunctions.h>
#include <Common/Exception.h>
#include <base/DateLUTImpl.h>
#include <base/DateLUT.h>
#include <Common/DateLUTImpl.h>
#include <Common/DateLUT.h>
#include <Columns/ColumnVector.h>
#include <Columns/ColumnDecimal.h>
#include <Functions/FunctionHelpers.h>

View File

@ -1,5 +1,5 @@
#pragma once
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
#include <DataTypes/DataTypeDate.h>
#include <DataTypes/DataTypeDate32.h>

View File

@ -1,6 +1,6 @@
#pragma once
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <DataTypes/DataTypeInterval.h>
#include <Functions/IFunction.h>

View File

@ -1,4 +1,4 @@
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
#include <Core/DecimalFunctions.h>
#include <IO/WriteHelpers.h>

View File

@ -4,7 +4,7 @@
#include <DataTypes/DataTypeDateTime.h>
#include <DataTypes/DataTypeDateTime64.h>
#include <Columns/ColumnString.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
namespace DB

View File

@ -14,7 +14,7 @@
#include <IO/WriteHelpers.h>
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
#include <base/find_symbols.h>
#include <Core/DecimalFunctions.h>

View File

@ -5,7 +5,7 @@
#include <Core/ServerUUID.h>
#include <Common/SymbolIndex.h>
#include <Common/DNSResolver.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#if defined(OS_LINUX)
# include <Poco/Environment.h>

View File

@ -3,7 +3,7 @@
#include <DataTypes/DataTypeString.h>
#include <DataTypes/DataTypeNullable.h>
#include <DataTypes/DataTypeDateTime.h>
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
#include <Core/Field.h>

View File

@ -1,4 +1,4 @@
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeDate.h>
#include <DataTypes/DataTypeDate32.h>

View File

@ -1,4 +1,4 @@
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <Core/Field.h>

View File

@ -1,4 +1,4 @@
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <Core/Field.h>

View File

@ -8,9 +8,9 @@
#include <type_traits>
#include <base/DateLUT.h>
#include <base/LocalDate.h>
#include <base/LocalDateTime.h>
#include <Common/DateLUT.h>
#include <Common/LocalDate.h>
#include <Common/LocalDateTime.h>
#include <base/StringRef.h>
#include <base/arithmeticOverflow.h>
#include <base/unit.h>

View File

@ -9,9 +9,9 @@
#include <pcg-random/pcg_random.hpp>
#include <base/DateLUT.h>
#include <base/LocalDate.h>
#include <base/LocalDateTime.h>
#include <Common/DateLUT.h>
#include <Common/LocalDate.h>
#include <Common/LocalDateTime.h>
#include <base/find_symbols.h>
#include <base/StringRef.h>
#include <base/DecomposedFloat.h>

View File

@ -1,4 +1,4 @@
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
#include <Common/StringUtils/StringUtils.h>
#include <IO/ReadBuffer.h>

View File

@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <IO/WriteHelpers.h>
#include <IO/WriteBufferFromString.h>

View File

@ -12,7 +12,7 @@
#include <DataTypes/DataTypeUUID.h>
#include <DataTypes/DataTypesNumber.h>
#include <Interpreters/ProfileEventsExt.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <base/types.h>
namespace DB

View File

@ -22,7 +22,7 @@
#include <Common/typeid_cast.h>
#include <Common/NaNUtils.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
#include <DataTypes/DataTypeAggregateFunction.h>

View File

@ -14,7 +14,7 @@
#include <DataTypes/DataTypeDate32.h>
#include <DataTypes/DataTypeDate.h>
#include <DataTypes/NestedUtils.h>
#include <base/DateLUTImpl.h>
#include <Common/DateLUTImpl.h>
#include <base/types.h>
#include <Processors/Chunk.h>
#include <Columns/ColumnString.h>

View File

@ -1,7 +1,7 @@
#include <Processors/Merges/Algorithms/GraphiteRollupSortedAlgorithm.h>
#include <AggregateFunctions/IAggregateFunction.h>
#include <base/DateLUTImpl.h>
#include <base/DateLUT.h>
#include <Common/DateLUTImpl.h>
#include <Common/DateLUT.h>
#include <DataTypes/DataTypeDateTime.h>

View File

@ -3,7 +3,7 @@
#include <Storages/TTLDescription.h>
#include <Storages/MergeTree/MergeTreeDataPartTTLInfo.h>
#include <Storages/MergeTree/IMergeTreeDataPart.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
namespace DB
{

View File

@ -6,7 +6,7 @@
#include <Storages/MergeTree/MergeTreeDataPartTTLInfo.h>
#include <Processors/TTL/ITTLAlgorithm.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
namespace DB
{

View File

@ -7,7 +7,7 @@
#include <Processors/TTL/ITTLAlgorithm.h>
#include <Processors/TTL/TTLDeleteAlgorithm.h>
#include <base/DateLUT.h>
#include <Common/DateLUT.h>
namespace DB
{

View File

@ -6,7 +6,7 @@
#include <Poco/Util/LayeredConfiguration.h>
#include <IO/HTTPCommon.h>
#include <base/getResource.h>
#include <Common/getResource.h>
namespace DB

View File

@ -6,7 +6,7 @@
#include <filesystem>
#include <unistd.h>
#include <sys/inotify.h>
#include <sys/poll.h>
#include <poll.h>
namespace DB
{

View File

@ -3,7 +3,7 @@
#include <Storages/System/attachSystemTablesImpl.h>
#include <Parsers/ParserCreateQuery.h>
#include <Parsers/parseQuery.h>
#include <base/getResource.h>
#include <Common/getResource.h>
namespace DB
{

View File

@ -4,7 +4,7 @@
42.42 6.513 42.419169
42.42 3.4875 42.417263671875
1 0.8427007929497149 0.15729920705028513
42.42 115.60113124678627 1.6029995567009473e50
42.42 115.601131 1.603
0 0 1 0
3.14159265 0 -1 -0
1 1.5707963267948966 0 0.7853981633974483
@ -14,7 +14,7 @@
42.42 6.513 42.419169
42.42 3.4875 42.417263671875
1 0.8427007929497149 0.15729920705028513
42.42 115.60113124678627 1.6029995567009473e50
42.42 115.601131 1.603
0 0 1 0
3.14159265358979328 0 -1 -0
1 1.5707963267948966 0 0.7853981633974483
@ -24,7 +24,7 @@
42.42 6.513 42.419169
42.42 3.4875 42.417263671875
1 0.8427007929497149 0.15729920705028513
42.42 115.60113124678627 1.6029995567009473e50
42.42 115.601131 1.603
0 0 1 0
3.14159265358979 0 -1 -0
1 1.5707963267948966 0 0.7853981633974483

View File

@ -5,7 +5,7 @@ SELECT toDecimal32('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, round(exp10(
SELECT toDecimal32('42.42', 4) AS x, toDecimal32(sqrt(x), 3) AS y, y * y;
SELECT toDecimal32('42.42', 4) AS x, toDecimal32(cbrt(x), 4) AS y, toDecimal64(y, 4) * y * y;
SELECT toDecimal32('1.0', 5) AS x, erf(x), erfc(x);
SELECT toDecimal32('42.42', 4) AS x, lgamma(x), tgamma(x);
SELECT toDecimal32('42.42', 4) AS x, round(lgamma(x), 6), round(tgamma(x) / 1e50, 6);
SELECT toDecimal32('0.0', 2) AS x, round(sin(x), 8), round(cos(x), 8), round(tan(x), 8);
SELECT toDecimal32(pi(), 8) AS x, round(sin(x), 8), round(cos(x), 8), round(tan(x), 8);
@ -19,7 +19,7 @@ SELECT toDecimal64('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, round(exp10(
SELECT toDecimal64('42.42', 4) AS x, toDecimal32(sqrt(x), 3) AS y, y * y;
SELECT toDecimal64('42.42', 4) AS x, toDecimal32(cbrt(x), 4) AS y, toDecimal64(y, 4) * y * y;
SELECT toDecimal64('1.0', 5) AS x, erf(x), erfc(x);
SELECT toDecimal64('42.42', 4) AS x, lgamma(x), tgamma(x);
SELECT toDecimal64('42.42', 4) AS x, round(lgamma(x), 6), round(tgamma(x) / 1e50, 6);
SELECT toDecimal64('0.0', 2) AS x, round(sin(x), 8), round(cos(x), 8), round(tan(x), 8);
SELECT toDecimal64(pi(), 17) AS x, round(sin(x), 8), round(cos(x), 8), round(tan(x), 8);
@ -33,7 +33,7 @@ SELECT toDecimal128('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, round(exp10
SELECT toDecimal128('42.42', 4) AS x, toDecimal32(sqrt(x), 3) AS y, y * y;
SELECT toDecimal128('42.42', 4) AS x, toDecimal32(cbrt(x), 4) AS y, toDecimal64(y, 4) * y * y;
SELECT toDecimal128('1.0', 5) AS x, erf(x), erfc(x);
SELECT toDecimal128('42.42', 4) AS x, lgamma(x), tgamma(x);
SELECT toDecimal128('42.42', 4) AS x, round(lgamma(x), 6), round(tgamma(x) / 1e50, 6);
SELECT toDecimal128('0.0', 2) AS x, round(sin(x), 8), round(cos(x), 8), round(tan(x), 8);
SELECT toDecimal128(pi(), 14) AS x, round(sin(x), 8), round(cos(x), 8), round(tan(x), 8);

View File

@ -1,8 +1,8 @@
[[[(1,2.9),(1,4),(4,4),(4,1),(2.9,1),(3,0),(0,0),(0,3),(1,2.9)]]]
[[[(4.3666052904432435,50.84337386140151),(4.366227,50.840809),(4.344961,50.833264),(4.338074,50.848677),(4.346693,50.858306),(4.3526804582393535,50.856658100365976),(4.3613577,50.8651821),(4.3613148,50.8651279),(4.3904543,50.8564867),(4.3830299,50.8428851),(4.3666052904432435,50.84337386140151)]]]
[[[(4.366605,50.843374),(4.366227,50.840809),(4.344961,50.833264),(4.338074,50.848677),(4.346693,50.858306),(4.35268,50.856658),(4.361358,50.865182),(4.361315,50.865128),(4.390454,50.856487),(4.38303,50.842885),(4.366605,50.843374)]]]
-------- MultiPolygon with Polygon
MULTIPOLYGON(((35.5408 58.9593,37.2817 59.9768,38.7325 59.9465,36.9725 59.0149,37.3119 59.0258,37.8553 58.9075,39.7299 59.9314,44.4751 59.81,44.4146 55.3097,40.0925 52.1652,38.3395 52.1652,39.1456 52.7573,38.0214 52.8989,37.1608 52.2393,35.4682 52.2022,36.5022 53.0008,35.3776 53.0462,35.3645 53.076,34.2895 52.2208,32.5969 52.2208,33.4048 52.8423,33.1712 52.8276,32.5275 53.1741,31.2368 52.1652,29.7861 52.1466,32.2523 53.964,31.8748 54.1736,29.3931 52.2763,29.4536 59.7796,30.5719 59.9919,30.4812 58.8542,32.3249 59.9465,33.6548 59.9465,30.179 57.9196,30.179 56.9764,32.2175 58.3664,32.2342 58.4928,32.5691 58.5924,34.8637 59.9768,36.2843 59.9616,34.0496 58.6717,34.9952 58.6226,35.3712 58.8556,34.6522 58.9167,35.5408 58.9593),(36.4989 58.7512,36.1498 58.553,36.3447 58.5402,36.0877 58.5174,35.4314 58.1349,36.403 58.0507,36.5949 58.1673,36.0123 58.2869,37.191 58.6819,36.4989 58.7512),(34.4816 56.8232,34.8098 57.0409,33.5602 56.9781,33.3418 56.8364,33.8361 56.6953,34.1885 56.6259,34.3867 56.7596,34.229 56.7948,34.4816 56.8232),(35.9179 57.7512,35.7402 57.7909,36.0848 57.855,36.3932 58.0447,35.1134 57.9454,34.6332 57.6538,35.613 57.5595,35.9179 57.7512),(36.8709 53.2765,37.135 53.4711,36.9794 53.5878,37.3119 53.9273,37.0035 54.2999,36.6985 54.0791,36.919 53.8561,36.3552 53.8269,36.1528 53.6763,36.8709 53.2765),(38.1601 55.1091,38.3093 55.1546,38.2609 55.1775,38.1601 55.1091),(38.1688 56.0758,38.4339 56.2361,37.5054 56.5484,37.2281 56.3799,38.1688 56.0758),(38.1319 56.0534,36.647 55.9411,37.6238 55.7402,38.1319 56.0534),(37.2824 55.5258,36.8283 55.4471,37.06 55.3843,37.2824 55.5258),(36.151 54.791,36.0123 54.7554,36.0472 54.7217,36.151 54.791),(34.9611 53.9765,34.894 54.1226,35.6193 54.4929,34.9706 54.9262,34.7231 54.7576,35.0753 54.5981,34.1081 54.1757,34.7279 53.8116,34.9611 53.9765),(38.2312 56.9795,37.565 56.5843,38.9742 56.8774,38.4915 57.1308,38.2699 57.0021,38.3093 56.9929,38.2312 56.9795),(36.5334 56.6753,36.375 56.6455,36.4446 56.6242,36.5334 56.6753),(36.1999 57.0022,36.9794 57.0751,36.4587 57.1544,36.1999 57.0022),(34.6028 58.3749,33.6245 58.271,34.3593 58.2189,34.6028 58.3749),(33.7581 57.8255,33.2316 57.7748,33.6325 57.7419,33.7581 57.8255),(31.6069 56.3194,31.7506 56.8609,31.6514 57.1258,30.3301 56.1942,30.2394 55.2753,31.6069 56.3194),(34.2274 57.4023,34.0208 57.2724,35.0338 57.1875,35.4682 57.4674,34.2274 57.4023),(31.7782 55.7778,30.2092 54.6331,30.2394 53.6774,31.7439 54.8677,31.8413 54.9989,32.204 55.5156,31.7782 55.7778),(33.7222 56.3063,32.8387 56.3117,33.5244 56.1686,33.7222 56.3063),(33.1204 55.8832,32.748 55.9072,32.9547 55.7645,33.1204 55.8832),(35.2275 55.0993,36.4354 55.3441,35.7505 55.4454,35.2275 55.0993),(35.9817 55.5958,36.5563 55.6352,36.193 55.7319,35.9817 55.5958),(35.0954 55.822,35.3188 55.9582,34.7331 56.1049,34.4996 55.9565,35.0954 55.822),(34.9721 55.7463,34.2598 55.8023,33.6125 55.3778,34.3709 55.3709,34.9721 55.7463),(35.6571 56.1619,36.0233 56.3789,35.4083 56.5254,35.2273 56.414,35.71 56.3117,35.0485 56.303,34.744 56.1118,35.6571 56.1619),(40.2143 54.467,40.3948 54.4403,40.6064 54.034,39.9716 53.9807,40.2437 53.5878,39.5485 53.5878,39.9942 53.358,43.0243 55.3269,43.0243 56.2614,40.2143 54.467),(38.5511 53.2922,38.4609 53.226,39.2704 52.8471,39.9877 53.3534,38.5511 53.2922),(40.5716 55.8007,43.0243 57.2554,43.0243 58.0797,40.4543 56.5923,40.4855 56.4957,40.2529 56.4682,39.8102 56.1914,39.8205 56.0763,40.425 56.1942,40.5716 55.8007),(40.5504 55.7875,39.7601 55.7544,39.8151 55.3187,40.5504 55.7875),(39.7863 57.025,42.5105 58.477,41.6944 58.8542,40.1389 58.048,40.2437 58.0478,40.3343 57.4673,39.7299 57.4673,39.7863 57.025),(38.0744 57.5312,38.3737 57.6908,38.3395 57.7103,38.8533 58.0638,38.432 58.2584,38.0535 58.0542,38.3395 57.9356,37.4328 57.7103,38.0744 57.5312),(37.9669 57.4734,37.1608 57.2554,37.4489 57.1909,37.9669 57.4734),(40.4136 58.7241,41.2108 59.1035,40.6366 59.3817,39.8163 58.9766,40.4552 58.9011,40.4136 58.7241),(39.7184 58.3823,39.6392 58.3821,39.6392 58.3427,39.7184 58.3823),(38.7465 58.4255,39.5485 58.7133,39.4085 58.7696,38.7465 58.4255)))
MULTIPOLYGON(((35.5408 58.9593,37.2817 59.9768,38.7325 59.9465,36.9725 59.0149,37.3119 59.0258,37.8553 58.9075,39.7299 59.9314,44.4751 59.81,44.4146 55.3097,40.0925 52.1652,38.3395 52.1652,39.1456 52.7572,38.0214 52.8989,37.1608 52.2393,35.4682 52.2022,36.5022 53.0008,35.3776 53.0462,35.3645 53.076,34.2895 52.2208,32.5969 52.2208,33.4048 52.8423,33.1712 52.8276,32.5275 53.1741,31.2368 52.1652,29.7861 52.1466,32.2523 53.964,31.8748 54.1736,29.3931 52.2763,29.4536 59.7796,30.5719 59.9919,30.4812 58.8542,32.3249 59.9465,33.6548 59.9465,30.179 57.9196,30.179 56.9764,32.2175 58.3664,32.2342 58.4928,32.5691 58.5924,34.8637 59.9768,36.2843 59.9616,34.0496 58.6717,34.9952 58.6226,35.3712 58.8556,34.6522 58.9167,35.5408 58.9593),(36.4989 58.7512,36.1498 58.553,36.3447 58.5402,36.0877 58.5174,35.4314 58.1349,36.403 58.0507,36.5949 58.1673,36.0123 58.2869,37.191 58.6819,36.4989 58.7512),(34.4816 56.8232,34.8098 57.0409,33.5602 56.9781,33.3418 56.8364,33.8361 56.6953,34.1885 56.6259,34.3867 56.7596,34.229 56.7948,34.4816 56.8232),(35.9179 57.7512,35.7402 57.7909,36.0848 57.855,36.3932 58.0447,35.1134 57.9454,34.6332 57.6538,35.613 57.5595,35.9179 57.7512),(36.8709 53.2765,37.135 53.4711,36.9794 53.5878,37.3119 53.9273,37.0035 54.2999,36.6985 54.0791,36.919 53.8561,36.3552 53.8269,36.1528 53.6763,36.8709 53.2765),(38.1601 55.1091,38.3093 55.1546,38.2609 55.1775,38.1601 55.1091),(38.1688 56.0758,38.4339 56.2361,37.5054 56.5484,37.2281 56.3799,38.1688 56.0758),(38.1319 56.0534,36.647 55.9411,37.6238 55.7402,38.1319 56.0534),(37.2824 55.5258,36.8283 55.4471,37.06 55.3843,37.2824 55.5258),(36.151 54.791,36.0123 54.7554,36.0472 54.7217,36.151 54.791),(34.9611 53.9765,34.894 54.1226,35.6193 54.4929,34.9706 54.9262,34.7231 54.7576,35.0753 54.5981,34.1081 54.1757,34.7279 53.8116,34.9611 53.9765),(38.2312 56.9795,37.565 56.5843,38.9742 56.8774,38.4915 57.1308,38.2699 57.0021,38.3093 56.9929,38.2312 56.9795),(36.5334 56.6753,36.375 56.6455,36.4446 56.6242,36.5334 56.6753),(36.1999 57.0022,36.9794 57.0751,36.4587 57.1544,36.1999 57.0022),(34.6028 58.3749,33.6245 58.271,34.3593 58.2189,34.6028 58.3749),(33.7581 57.8255,33.2316 57.7748,33.6325 57.7419,33.7581 57.8255),(31.6069 56.3194,31.7506 56.8609,31.6514 57.1258,30.3301 56.1942,30.2394 55.2753,31.6069 56.3194),(34.2274 57.4023,34.0208 57.2724,35.0338 57.1875,35.4682 57.4674,34.2274 57.4023),(31.7782 55.7778,30.2092 54.6331,30.2394 53.6774,31.7439 54.8677,31.8413 54.9989,32.204 55.5156,31.7782 55.7778),(33.7222 56.3063,32.8387 56.3117,33.5244 56.1686,33.7222 56.3063),(33.1204 55.8832,32.748 55.9072,32.9547 55.7645,33.1204 55.8832),(35.2275 55.0993,36.4354 55.3441,35.7505 55.4454,35.2275 55.0993),(35.9817 55.5958,36.5563 55.6352,36.193 55.7319,35.9817 55.5958),(35.0954 55.822,35.3188 55.9582,34.7331 56.1049,34.4996 55.9565,35.0954 55.822),(34.9721 55.7463,34.2598 55.8023,33.6125 55.3778,34.3709 55.3709,34.9721 55.7463),(35.6571 56.1619,36.0233 56.3789,35.4083 56.5254,35.2273 56.414,35.71 56.3117,35.0485 56.303,34.744 56.1118,35.6571 56.1619),(40.2143 54.467,40.3948 54.4403,40.6064 54.034,39.9716 53.9807,40.2437 53.5878,39.5485 53.5878,39.9942 53.358,43.0243 55.3269,43.0243 56.2614,40.2143 54.467),(38.5511 53.2922,38.4609 53.226,39.2704 52.8471,39.9877 53.3534,38.5511 53.2922),(40.5716 55.8007,43.0243 57.2554,43.0243 58.0797,40.4543 56.5923,40.4855 56.4957,40.2529 56.4682,39.8102 56.1914,39.8205 56.0763,40.425 56.1942,40.5716 55.8007),(40.5504 55.7875,39.7601 55.7544,39.8151 55.3187,40.5504 55.7875),(39.7863 57.025,42.5105 58.477,41.6944 58.8542,40.1389 58.048,40.2437 58.0478,40.3343 57.4673,39.7299 57.4673,39.7863 57.025),(38.0744 57.5312,38.3737 57.6908,38.3395 57.7103,38.8533 58.0638,38.432 58.2584,38.0535 58.0542,38.3395 57.9356,37.4328 57.7103,38.0744 57.5312),(37.9669 57.4734,37.1608 57.2554,37.4489 57.1909,37.9669 57.4734),(40.4136 58.7241,41.2108 59.1035,40.6366 59.3817,39.8163 58.9766,40.4552 58.9011,40.4136 58.7241),(39.7184 58.3823,39.6392 58.3821,39.6392 58.3427,39.7184 58.3823),(38.7465 58.4255,39.5485 58.7133,39.4085 58.7696,38.7465 58.4255)))
-------- MultiPolygon with Polygon with Holes
MULTIPOLYGON(((24.3677 61.4598,26.6528 61.1008,26.8726 61.7107,30.564 61.0583,31.3989 62.0215,36.0132 61.1432,36.8921 62.0009,42.6489 60.6301,43.5718 61.3757,47.0435 59.8889,49.5923 60.0868,49.1528 58.1707,51.9214 57.9148,50.2515 56.1455,52.6685 55.826,51.6577 54.2909,52.8882 53.9302,50.647 53.0148,51.394 52.4828,48.0542 51.1793,49.2847 50.5414,47.1753 49.153,43.9233 49.8096,42.561 48.7779,36.936 49.6676,35.2661 48.7489,32.8052 49.5252,27.2241 48.9802,26.1255 50.4015,21.2036 50.205,20.0171 51.5634,17.4683 53.0148,19.4458 54.0852,19.4458 55.8753,19.5776 57.4922,19.5776 58.6769,24.3677 61.4598),(24.4556 59.4227,21.2036 58.4937,21.3354 56.897,21.5991 55.9246,25.2026 55.9984,28.8501 57.0646,27.0923 57.8448,28.8062 59.1759,26.2573 59.1759,24.4556 59.4227),(33.1079 56.9523,33.1392 56.8934,33.7182 56.7292,35.1489 56.5859,34.229 56.7948,36.9794 57.0751,35.7705 57.2554,37.0097 57.4998,35.7402 57.7909,37.1608 58.0478,36.0123 58.2869,37.191 58.6819,34.6522 58.9167,37.2327 59.0233,37.1118 59.6677,35.1343 59.8448,31.9702 58.9727,32.25 58.4976,33.4734 58.8542,34.7428 59.5659,33.8361 58.6819,36.3447 58.5402,33.6245 58.271,36.4354 58.0478,33.2316 57.7748,36.1936 57.4998,33.1712 57.337,36.0727 57.0915,33.1079 56.9523),(37.0604 52.9744,34.9585 51.4814,36.5405 50.4015,39.6606 50.2893,39.7925 52.1335,41.77 50.6808,44.4946 51.9713,47.3071 52.5095,44.0552 53.5403,46.604 53.6967,47.6147 55.4041,45.3735 55.4041,42.8247 56.5837,40.4412 56.1511,40.5761 55.7884,39.7601 55.7544,39.8205 55.2753,40.3948 55.2408,40.3948 54.8773,39.5485 54.8773,39.5485 54.5631,40.3948 54.4403,40.6064 54.034,39.9716 53.9807,40.2437 53.5878,39.5485 53.5878,40.0019 53.354,38.3395 53.2817,39.5787 52.6996,37.8559 52.9188,37.4471 53.2343,37.2165 53.0798,37.4328 52.9552,37.0604 52.9744),(31.627 54.7093,29.5972 55.5037,29.1577 55.7518,22.5659 55.1286,22.5659 53.5403,22.0386 51.4814,26.2573 51.4266,30.1245 50.5414,32.1899 51.1793,30.1245 53.1731,32.4808 53.1989,32.0831 53.408,32.476 53.8383,31.4182 54.4227,31.627 54.7093),(34.7731 53.3243,34.7731 53.1793,35.0903 53.1731,34.7731 53.3243),(36.9508 55.414,37.7653 55.1891,36.8822 54.975,37.0572 54.7635,38.3093 55.1546,37.7955 55.3956,38.4907 55.5327,38.3184 55.7179,38.0262 55.6546,38.0373 55.6523,37.9482 55.6376,36.9508 55.414),(38.3092 56.9929,38.5798 57.0849,38.2186 57.2717,38.7325 57.4835,38.3395 57.7103,38.8533 58.0638,38.3698 58.2869,39.5485 58.7133,38.8838 58.9777,38.0944 58.8545,38.5813 58.7446,37.4026 58.3187,38.3395 57.9356,37.4328 57.7103,38.128 57.516,37.1608 57.2554,38.3092 56.9929),(38.309 56.9928,36.375 56.6455,36.8799 56.4895,38.309 56.9928),(40.3237 57.5365,42.6929 58.0314,40.8911 59.2659,39.2792 59.0373,40.4552 58.9011,40.3343 58.3821,39.6392 58.3821,39.6392 58.0478,40.2437 58.0478,40.3237 57.5365),(40.0149 57.4677,39.7299 57.4673,39.7379 57.4051,40.0149 57.4677)))
MULTIPOLYGON(((24.3677 61.4598,26.6528 61.1008,26.8726 61.7107,30.564 61.0583,31.3989 62.0215,36.0132 61.1432,36.8921 62.0009,42.6489 60.6301,43.5718 61.3757,47.0435 59.8889,49.5923 60.0868,49.1528 58.1707,51.9214 57.9148,50.2515 56.1456,52.6685 55.826,51.6577 54.2909,52.8882 53.9302,50.647 53.0148,51.394 52.4828,48.0542 51.1793,49.2847 50.5414,47.1753 49.153,43.9233 49.8096,42.561 48.7779,36.936 49.6676,35.2661 48.7489,32.8052 49.5252,27.2241 48.9802,26.1255 50.4015,21.2036 50.205,20.0171 51.5634,17.4683 53.0148,19.4458 54.0852,19.4458 55.8753,19.5776 57.4922,19.5776 58.6769,24.3677 61.4598),(24.4556 59.4227,21.2036 58.4937,21.3354 56.897,21.5991 55.9246,25.2026 55.9984,28.8501 57.0646,27.0923 57.8448,28.8062 59.1759,26.2573 59.1759,24.4556 59.4227),(33.1079 56.9523,33.1392 56.8934,33.7182 56.7292,35.1489 56.5859,34.229 56.7948,36.9794 57.0751,35.7705 57.2554,37.0097 57.4998,35.7402 57.7909,37.1608 58.0478,36.0123 58.2869,37.191 58.6819,34.6522 58.9167,37.2327 59.0233,37.1118 59.6677,35.1343 59.8448,31.9702 58.9727,32.25 58.4976,33.4734 58.8542,34.7428 59.5659,33.8361 58.6819,36.3447 58.5402,33.6245 58.271,36.4354 58.0478,33.2316 57.7748,36.1936 57.4998,33.1712 57.337,36.0727 57.0915,33.1079 56.9523),(37.0604 52.9744,34.9585 51.4814,36.5405 50.4015,39.6606 50.2893,39.7925 52.1335,41.77 50.6808,44.4946 51.9713,47.3071 52.5095,44.0552 53.5403,46.604 53.6967,47.6147 55.4041,45.3735 55.4041,42.8247 56.5837,40.4412 56.1511,40.5761 55.7884,39.7601 55.7544,39.8205 55.2753,40.3948 55.2408,40.3948 54.8773,39.5485 54.8773,39.5485 54.5631,40.3948 54.4403,40.6064 54.034,39.9716 53.9807,40.2437 53.5878,39.5485 53.5878,40.0019 53.354,38.3395 53.2817,39.5787 52.6996,37.8559 52.9188,37.4471 53.2343,37.2165 53.0798,37.4328 52.9552,37.0604 52.9744),(31.627 54.7093,29.5972 55.5037,29.1577 55.7518,22.5659 55.1286,22.5659 53.5403,22.0386 51.4814,26.2573 51.4266,30.1245 50.5414,32.1899 51.1793,30.1245 53.1731,32.4808 53.1989,32.0831 53.408,32.476 53.8383,31.4182 54.4227,31.627 54.7093),(34.7731 53.3243,34.7731 53.1793,35.0903 53.1731,34.7731 53.3243),(36.9508 55.414,37.7653 55.1891,36.8822 54.975,37.0572 54.7635,38.3093 55.1546,37.7955 55.3956,38.4907 55.5327,38.3184 55.7179,38.0262 55.6546,38.0373 55.6523,37.9482 55.6376,36.9508 55.414),(38.3092 56.9929,38.5798 57.0849,38.2186 57.2717,38.7325 57.4835,38.3395 57.7103,38.8533 58.0638,38.3698 58.2869,39.5485 58.7133,38.8838 58.9777,38.0944 58.8545,38.5813 58.7446,37.4026 58.3187,38.3395 57.9356,37.4328 57.7103,38.128 57.516,37.1608 57.2554,38.3092 56.9929),(38.309 56.9928,36.375 56.6455,36.8799 56.4895,38.309 56.9928),(40.3237 57.5365,42.6929 58.0314,40.8911 59.2659,39.2792 59.0373,40.4552 58.9011,40.3343 58.3821,39.6392 58.3821,39.6392 58.0478,40.2437 58.0478,40.3237 57.5365),(40.0149 57.4677,39.7299 57.4673,39.7379 57.4051,40.0149 57.4677)))
-------- Polygon with Polygon with Holes
MULTIPOLYGON(((24.3677 61.4598,26.6528 61.1008,26.8726 61.7107,30.564 61.0583,31.3989 62.0215,36.0132 61.1432,36.8921 62.0009,42.6489 60.6301,43.5718 61.3757,47.0435 59.8889,49.5923 60.0868,49.1528 58.1707,51.9214 57.9148,50.2515 56.1455,52.6685 55.826,51.6577 54.2909,52.8882 53.9302,50.647 53.0148,51.394 52.4828,48.0542 51.1793,49.2847 50.5414,47.1753 49.153,43.9233 49.8096,42.561 48.7779,36.936 49.6676,35.2661 48.7489,32.8052 49.5252,27.2241 48.9802,26.1255 50.4015,21.2036 50.205,20.0171 51.5634,17.4683 53.0148,19.4458 54.0852,19.4458 55.8753,19.5776 57.4922,19.5776 58.6769,24.3677 61.4598),(24.4556 59.4227,21.2036 58.4937,21.3354 56.897,21.5991 55.9246,25.2026 55.9984,28.8501 57.0646,27.0923 57.8448,28.8062 59.1759,26.2573 59.1759,24.4556 59.4227),(32.6512 57.792,32.9378 57.2699,36.7912 59.6986,35.9475 59.7758,32.6512 57.792),(33.2446 56.7729,34.2635 56.6767,37.6322 58.7797,37.2876 58.7226,37.2102 59.1452,33.2446 56.7729),(36.1815 56.4715,41.168 59.0834,40.9299 59.2404,40.8804 59.2644,40.2079 59.1718,35.4536 56.5531,36.1815 56.4715),(30.7705 55.0525,30.2092 54.6331,30.2394 53.6774,31.5682 54.7333,30.7705 55.0525),(33.8733 53.1922,34.3351 53.53,33.5144 53.9057,32.5603 53.1989,33.8733 53.1922),(31.1968 52.1649,29.7861 52.1466,30.5785 52.7531,30.3098 53.0028,29.3931 52.2763,29.4171 55.606,29.1577 55.7518,22.5659 55.1286,22.5659 53.5403,22.0386 51.4814,26.2573 51.4266,30.1245 50.5414,32.1899 51.1793,31.1968 52.1649),(31.1682 53.1903,32.6907 54.2663,32.2591 54.4483,30.5408 53.1811,31.1682 53.1903),(39.4328 55.9511,37.2766 54.4948,37.7431 53.9104,41.4519 56.3413,39.4328 55.9511),(40.9691 57.677,42.2498 58.3455,41.5887 58.8012,38.1759 56.9472,39.0894 57.2553,40.9691 57.677),(37.1934 55.4694,36.5845 55.3291,36.7219 55.1665,37.1934 55.4694),(32.2964 58.4175,34.2247 59.6064,31.9702 58.9727,32.2964 58.4175),(35.9681 52.2157,34.9585 51.4814,36.5405 50.4015,39.6606 50.2893,39.7925 52.1335,41.77 50.6808,44.4946 51.9713,47.3071 52.5095,44.0552 53.5403,46.604 53.6967,47.6147 55.4041,45.3735 55.4041,44.4212 55.8594,44.4146 55.3097,40.0925 52.1652,38.3395 52.1652,43.0243 55.3269,43.0243 56.2614,37.1608 52.2393,35.9681 52.2157)))
MULTIPOLYGON(((24.3677 61.4598,26.6528 61.1008,26.8726 61.7107,30.564 61.0583,31.3989 62.0215,36.0132 61.1432,36.8921 62.0009,42.6489 60.6301,43.5718 61.3757,47.0435 59.8889,49.5923 60.0868,49.1528 58.1707,51.9214 57.9148,50.2515 56.1456,52.6685 55.826,51.6577 54.2909,52.8882 53.9302,50.647 53.0148,51.394 52.4828,48.0542 51.1793,49.2847 50.5414,47.1753 49.153,43.9233 49.8096,42.561 48.7779,36.936 49.6676,35.2661 48.7489,32.8052 49.5252,27.2241 48.9802,26.1255 50.4015,21.2036 50.205,20.0171 51.5634,17.4683 53.0148,19.4458 54.0852,19.4458 55.8753,19.5776 57.4922,19.5776 58.6769,24.3677 61.4598),(24.4556 59.4227,21.2036 58.4937,21.3354 56.897,21.5991 55.9246,25.2026 55.9984,28.8501 57.0646,27.0923 57.8448,28.8062 59.1759,26.2573 59.1759,24.4556 59.4227),(32.6512 57.792,32.9378 57.2699,36.7912 59.6986,35.9475 59.7758,32.6512 57.792),(33.2446 56.7729,34.2635 56.6767,37.6322 58.7797,37.2876 58.7226,37.2102 59.1452,33.2446 56.7729),(36.1815 56.4715,41.168 59.0834,40.9299 59.2404,40.8804 59.2644,40.2079 59.1718,35.4536 56.5531,36.1815 56.4715),(30.7705 55.0525,30.2092 54.6331,30.2394 53.6774,31.5682 54.7333,30.7705 55.0525),(33.8733 53.1922,34.3351 53.53,33.5144 53.9057,32.5603 53.1989,33.8733 53.1922),(31.1968 52.1649,29.7861 52.1466,30.5785 52.7531,30.3098 53.0028,29.3931 52.2763,29.4171 55.606,29.1577 55.7518,22.5659 55.1286,22.5659 53.5403,22.0386 51.4814,26.2573 51.4266,30.1245 50.5414,32.1899 51.1793,31.1968 52.1649),(31.1682 53.1903,32.6907 54.2663,32.2591 54.4483,30.5408 53.1811,31.1682 53.1903),(39.4328 55.9511,37.2766 54.4948,37.7431 53.9104,41.4519 56.3413,39.4328 55.9511),(40.9691 57.677,42.2498 58.3455,41.5887 58.8012,38.1759 56.9472,39.0894 57.2553,40.9691 57.677),(37.1934 55.4694,36.5845 55.3291,36.7219 55.1665,37.1934 55.4694),(32.2964 58.4175,34.2247 59.6064,31.9702 58.9727,32.2964 58.4175),(35.9681 52.2157,34.9585 51.4814,36.5405 50.4015,39.6606 50.2893,39.7925 52.1335,41.77 50.6808,44.4946 51.9713,47.3071 52.5095,44.0552 53.5403,46.604 53.6967,47.6147 55.4041,45.3735 55.4041,44.4212 55.8594,44.4146 55.3097,40.0925 52.1652,38.3395 52.1652,43.0243 55.3269,43.0243 56.2614,37.1608 52.2393,35.9681 52.2157)))

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More