mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge remote-tracking branch 'upstream/master' into fix27
This commit is contained in:
commit
5b9c12ba3b
1
contrib/CMakeLists.txt
vendored
1
contrib/CMakeLists.txt
vendored
@ -250,6 +250,7 @@ if (USE_EMBEDDED_COMPILER AND USE_INTERNAL_LLVM_LIBRARY)
|
|||||||
endif ()
|
endif ()
|
||||||
set (LLVM_ENABLE_EH 1 CACHE INTERNAL "")
|
set (LLVM_ENABLE_EH 1 CACHE INTERNAL "")
|
||||||
set (LLVM_ENABLE_RTTI 1 CACHE INTERNAL "")
|
set (LLVM_ENABLE_RTTI 1 CACHE INTERNAL "")
|
||||||
|
set (LLVM_ENABLE_PIC 0 CACHE INTERNAL "")
|
||||||
set (LLVM_TARGETS_TO_BUILD "X86;AArch64" CACHE STRING "")
|
set (LLVM_TARGETS_TO_BUILD "X86;AArch64" CACHE STRING "")
|
||||||
add_subdirectory (llvm/llvm)
|
add_subdirectory (llvm/llvm)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -6,88 +6,87 @@ SET(AWS_EVENT_STREAM_LIBRARY_DIR ${ClickHouse_SOURCE_DIR}/contrib/aws-c-event-st
|
|||||||
|
|
||||||
OPTION(USE_AWS_MEMORY_MANAGEMENT "Aws memory management" OFF)
|
OPTION(USE_AWS_MEMORY_MANAGEMENT "Aws memory management" OFF)
|
||||||
configure_file("${AWS_CORE_LIBRARY_DIR}/include/aws/core/SDKConfig.h.in"
|
configure_file("${AWS_CORE_LIBRARY_DIR}/include/aws/core/SDKConfig.h.in"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/include/aws/core/SDKConfig.h" @ONLY)
|
"${CMAKE_CURRENT_BINARY_DIR}/include/aws/core/SDKConfig.h" @ONLY)
|
||||||
|
|
||||||
configure_file("${AWS_COMMON_LIBRARY_DIR}/include/aws/common/config.h.in"
|
configure_file("${AWS_COMMON_LIBRARY_DIR}/include/aws/common/config.h.in"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/include/aws/common/config.h" @ONLY)
|
"${CMAKE_CURRENT_BINARY_DIR}/include/aws/common/config.h" @ONLY)
|
||||||
|
|
||||||
|
|
||||||
file(GLOB AWS_CORE_SOURCES
|
file(GLOB AWS_CORE_SOURCES
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/auth/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/auth/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/client/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/client/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/http/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/http/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/http/standard/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/http/standard/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/http/curl/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/http/curl/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/config/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/config/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/external/cjson/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/external/cjson/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/external/tinyxml2/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/external/tinyxml2/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/internal/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/internal/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/monitoring/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/monitoring/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/net/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/net/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/linux-shared/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/linux-shared/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/platform/linux-shared/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/platform/linux-shared/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/base64/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/base64/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/event/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/event/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/crypto/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/crypto/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/crypto/openssl/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/crypto/openssl/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/crypto/factory/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/crypto/factory/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/json/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/json/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/logging/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/logging/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/memory/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/memory/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/memory/stl/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/memory/stl/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/stream/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/stream/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/threading/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/threading/*.cpp"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/source/utils/xml/*.cpp"
|
"${AWS_CORE_LIBRARY_DIR}/source/utils/xml/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB AWS_S3_SOURCES
|
file(GLOB AWS_S3_SOURCES
|
||||||
"${AWS_S3_LIBRARY_DIR}/source/*.cpp"
|
"${AWS_S3_LIBRARY_DIR}/source/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB AWS_S3_MODEL_SOURCES
|
file(GLOB AWS_S3_MODEL_SOURCES
|
||||||
"${AWS_S3_LIBRARY_DIR}/source/model/*.cpp"
|
"${AWS_S3_LIBRARY_DIR}/source/model/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB AWS_EVENT_STREAM_SOURCES
|
file(GLOB AWS_EVENT_STREAM_SOURCES
|
||||||
"${AWS_EVENT_STREAM_LIBRARY_DIR}/source/*.c"
|
"${AWS_EVENT_STREAM_LIBRARY_DIR}/source/*.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB AWS_COMMON_SOURCES
|
file(GLOB AWS_COMMON_SOURCES
|
||||||
"${AWS_COMMON_LIBRARY_DIR}/source/*.c"
|
"${AWS_COMMON_LIBRARY_DIR}/source/*.c"
|
||||||
"${AWS_COMMON_LIBRARY_DIR}/source/posix/*.c"
|
"${AWS_COMMON_LIBRARY_DIR}/source/posix/*.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB AWS_CHECKSUMS_SOURCES
|
file(GLOB AWS_CHECKSUMS_SOURCES
|
||||||
"${AWS_CHECKSUMS_LIBRARY_DIR}/source/*.c"
|
"${AWS_CHECKSUMS_LIBRARY_DIR}/source/*.c"
|
||||||
"${AWS_CHECKSUMS_LIBRARY_DIR}/source/intel/*.c"
|
"${AWS_CHECKSUMS_LIBRARY_DIR}/source/intel/*.c"
|
||||||
"${AWS_CHECKSUMS_LIBRARY_DIR}/source/arm/*.c"
|
"${AWS_CHECKSUMS_LIBRARY_DIR}/source/arm/*.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB S3_UNIFIED_SRC
|
file(GLOB S3_UNIFIED_SRC
|
||||||
${AWS_EVENT_STREAM_SOURCES}
|
${AWS_EVENT_STREAM_SOURCES}
|
||||||
${AWS_COMMON_SOURCES}
|
${AWS_COMMON_SOURCES}
|
||||||
${AWS_S3_SOURCES}
|
${AWS_S3_SOURCES}
|
||||||
${AWS_S3_MODEL_SOURCES}
|
${AWS_S3_MODEL_SOURCES}
|
||||||
${AWS_CORE_SOURCES}
|
${AWS_CORE_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(S3_INCLUDES
|
set(S3_INCLUDES
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
"${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||||
"${AWS_COMMON_LIBRARY_DIR}/include/"
|
"${AWS_COMMON_LIBRARY_DIR}/include/"
|
||||||
"${AWS_EVENT_STREAM_LIBRARY_DIR}/include/"
|
"${AWS_EVENT_STREAM_LIBRARY_DIR}/include/"
|
||||||
"${AWS_S3_LIBRARY_DIR}/include/"
|
"${AWS_S3_LIBRARY_DIR}/include/"
|
||||||
"${AWS_CORE_LIBRARY_DIR}/include/"
|
"${AWS_CORE_LIBRARY_DIR}/include/"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/include/"
|
"${CMAKE_CURRENT_BINARY_DIR}/include/"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(aws_s3_checksums ${AWS_CHECKSUMS_SOURCES})
|
add_library(aws_s3_checksums ${AWS_CHECKSUMS_SOURCES})
|
||||||
target_include_directories(aws_s3_checksums PUBLIC "${AWS_CHECKSUMS_LIBRARY_DIR}/include/")
|
target_include_directories(aws_s3_checksums PUBLIC "${AWS_CHECKSUMS_LIBRARY_DIR}/include/")
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "" OR CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "" OR CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
target_compile_definitions(aws_s3_checksums PRIVATE "-DDEBUG_BUILD")
|
target_compile_definitions(aws_s3_checksums PRIVATE "-DDEBUG_BUILD")
|
||||||
endif()
|
endif()
|
||||||
set_target_properties(aws_s3_checksums PROPERTIES COMPILE_OPTIONS -fPIC)
|
|
||||||
set_target_properties(aws_s3_checksums PROPERTIES LINKER_LANGUAGE C)
|
set_target_properties(aws_s3_checksums PROPERTIES LINKER_LANGUAGE C)
|
||||||
set_property(TARGET aws_s3_checksums PROPERTY C_STANDARD 99)
|
set_property(TARGET aws_s3_checksums PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
|
@ -65,11 +65,6 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# For debug libs and exes, add "-d" postfix
|
|
||||||
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
|
||||||
set(CMAKE_DEBUG_POSTFIX "-d")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# initialize CURL_LIBS
|
# initialize CURL_LIBS
|
||||||
set(CURL_LIBS "")
|
set(CURL_LIBS "")
|
||||||
|
|
||||||
@ -115,8 +110,6 @@ if(ENABLE_IPV6 AND NOT WIN32)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
curl_nroff_check()
|
|
||||||
|
|
||||||
# We need ansi c-flags, especially on HP
|
# We need ansi c-flags, especially on HP
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
|
set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
|
||||||
set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
|
set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
|
||||||
@ -132,21 +125,21 @@ include(CheckCSourceCompiles)
|
|||||||
|
|
||||||
if(ENABLE_THREADED_RESOLVER)
|
if(ENABLE_THREADED_RESOLVER)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
if(WIN32)
|
set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT})
|
||||||
set(USE_THREADS_WIN32 ON)
|
set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT})
|
||||||
else()
|
|
||||||
set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT})
|
|
||||||
set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT})
|
|
||||||
endif()
|
|
||||||
set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for all needed libraries
|
# Check for all needed libraries
|
||||||
check_library_exists_concat("${CMAKE_DL_LIBS}" dlopen HAVE_LIBDL)
|
|
||||||
check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
|
|
||||||
check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL)
|
|
||||||
|
|
||||||
check_function_exists(gethostname HAVE_GETHOSTNAME)
|
# We don't want any plugin loading at runtime. It is harmful.
|
||||||
|
#check_library_exists_concat("${CMAKE_DL_LIBS}" dlopen HAVE_LIBDL)
|
||||||
|
|
||||||
|
# This is unneeded.
|
||||||
|
#check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
|
||||||
|
|
||||||
|
set (NOT_NEED_LIBNSL 1)
|
||||||
|
set (gethostname HAVE_GETHOSTNAME 1)
|
||||||
|
|
||||||
# From cmake/find/ssl.cmake
|
# From cmake/find/ssl.cmake
|
||||||
if (OPENSSL_FOUND)
|
if (OPENSSL_FOUND)
|
||||||
@ -167,10 +160,12 @@ if (OPENSSL_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for idn
|
# Check for idn
|
||||||
check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
|
# No, we don't need that.
|
||||||
|
# check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
|
||||||
|
|
||||||
# Check for symbol dlopen (same as HAVE_LIBDL)
|
# Check for symbol dlopen (same as HAVE_LIBDL)
|
||||||
check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
|
# We don't want any plugin loading at runtime. It is harmful.
|
||||||
|
# check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
|
||||||
|
|
||||||
# From /cmake/find/zlib.cmake
|
# From /cmake/find/zlib.cmake
|
||||||
if (ZLIB_FOUND)
|
if (ZLIB_FOUND)
|
||||||
@ -181,7 +176,7 @@ if (ZLIB_FOUND)
|
|||||||
list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
|
list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON)
|
option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" OFF)
|
||||||
if(ENABLE_UNIX_SOCKETS)
|
if(ENABLE_UNIX_SOCKETS)
|
||||||
include(CheckStructHasMember)
|
include(CheckStructHasMember)
|
||||||
check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
|
check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
|
||||||
@ -217,14 +212,14 @@ check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H)
|
|||||||
check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H)
|
check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H)
|
||||||
check_include_file_concat("alloca.h" HAVE_ALLOCA_H)
|
check_include_file_concat("alloca.h" HAVE_ALLOCA_H)
|
||||||
check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
|
check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||||
check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H)
|
#check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H)
|
||||||
check_include_file_concat("assert.h" HAVE_ASSERT_H)
|
check_include_file_concat("assert.h" HAVE_ASSERT_H)
|
||||||
check_include_file_concat("crypto.h" HAVE_CRYPTO_H)
|
check_include_file_concat("crypto.h" HAVE_CRYPTO_H)
|
||||||
check_include_file_concat("des.h" HAVE_DES_H)
|
check_include_file_concat("des.h" HAVE_DES_H)
|
||||||
check_include_file_concat("err.h" HAVE_ERR_H)
|
check_include_file_concat("err.h" HAVE_ERR_H)
|
||||||
check_include_file_concat("errno.h" HAVE_ERRNO_H)
|
check_include_file_concat("errno.h" HAVE_ERRNO_H)
|
||||||
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
|
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
|
||||||
check_include_file_concat("idn2.h" HAVE_IDN2_H)
|
#check_include_file_concat("idn2.h" HAVE_IDN2_H)
|
||||||
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
|
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
|
||||||
check_include_file_concat("io.h" HAVE_IO_H)
|
check_include_file_concat("io.h" HAVE_IO_H)
|
||||||
check_include_file_concat("krb.h" HAVE_KRB_H)
|
check_include_file_concat("krb.h" HAVE_KRB_H)
|
||||||
@ -259,7 +254,7 @@ check_include_file_concat("x509.h" HAVE_X509_H)
|
|||||||
|
|
||||||
check_include_file_concat("process.h" HAVE_PROCESS_H)
|
check_include_file_concat("process.h" HAVE_PROCESS_H)
|
||||||
check_include_file_concat("stddef.h" HAVE_STDDEF_H)
|
check_include_file_concat("stddef.h" HAVE_STDDEF_H)
|
||||||
check_include_file_concat("dlfcn.h" HAVE_DLFCN_H)
|
#check_include_file_concat("dlfcn.h" HAVE_DLFCN_H)
|
||||||
check_include_file_concat("malloc.h" HAVE_MALLOC_H)
|
check_include_file_concat("malloc.h" HAVE_MALLOC_H)
|
||||||
check_include_file_concat("memory.h" HAVE_MEMORY_H)
|
check_include_file_concat("memory.h" HAVE_MEMORY_H)
|
||||||
check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
|
check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
|
||||||
@ -276,30 +271,11 @@ check_type_size("int" SIZEOF_INT)
|
|||||||
check_type_size("__int64" SIZEOF___INT64)
|
check_type_size("__int64" SIZEOF___INT64)
|
||||||
check_type_size("long double" SIZEOF_LONG_DOUBLE)
|
check_type_size("long double" SIZEOF_LONG_DOUBLE)
|
||||||
check_type_size("time_t" SIZEOF_TIME_T)
|
check_type_size("time_t" SIZEOF_TIME_T)
|
||||||
if(NOT HAVE_SIZEOF_SSIZE_T)
|
|
||||||
if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
|
|
||||||
set(ssize_t long)
|
|
||||||
endif()
|
|
||||||
if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
|
|
||||||
set(ssize_t __int64)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
# off_t is sized later, after the HAVE_FILE_OFFSET_BITS test
|
|
||||||
|
|
||||||
if(HAVE_SIZEOF_LONG_LONG)
|
set(HAVE_LONGLONG 1)
|
||||||
set(HAVE_LONGLONG 1)
|
set(HAVE_LL 1)
|
||||||
set(HAVE_LL 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_file(RANDOM_FILE urandom /dev)
|
set(RANDOM_FILE /dev/urandom)
|
||||||
mark_as_advanced(RANDOM_FILE)
|
|
||||||
|
|
||||||
# Check for some functions that are used
|
|
||||||
if(HAVE_LIBWS2_32)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
|
|
||||||
elseif(HAVE_LIBSOCKET)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES socket)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME)
|
check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME)
|
||||||
check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
|
check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
|
||||||
@ -311,18 +287,15 @@ check_symbol_exists(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R)
|
|||||||
check_symbol_exists(strftime "${CURL_INCLUDES}" HAVE_STRFTIME)
|
check_symbol_exists(strftime "${CURL_INCLUDES}" HAVE_STRFTIME)
|
||||||
check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
|
check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
|
||||||
check_symbol_exists(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP)
|
check_symbol_exists(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP)
|
||||||
check_symbol_exists(stricmp "${CURL_INCLUDES}" HAVE_STRICMP)
|
#check_symbol_exists(stricmp "${CURL_INCLUDES}" HAVE_STRICMP)
|
||||||
check_symbol_exists(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI)
|
#check_symbol_exists(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI)
|
||||||
check_symbol_exists(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI)
|
#check_symbol_exists(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI)
|
||||||
check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM)
|
check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM)
|
||||||
if(NOT HAVE_STRNCMPI)
|
#check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
|
||||||
set(HAVE_STRCMPI)
|
|
||||||
endif()
|
|
||||||
check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
|
|
||||||
check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
|
check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
|
||||||
check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
|
check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
|
||||||
check_symbol_exists(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR)
|
check_symbol_exists(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR)
|
||||||
check_symbol_exists(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA)
|
#check_symbol_exists(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA)
|
||||||
check_symbol_exists(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R)
|
check_symbol_exists(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R)
|
||||||
check_symbol_exists(tcsetattr "${CURL_INCLUDES}" HAVE_TCSETATTR)
|
check_symbol_exists(tcsetattr "${CURL_INCLUDES}" HAVE_TCSETATTR)
|
||||||
check_symbol_exists(tcgetattr "${CURL_INCLUDES}" HAVE_TCGETATTR)
|
check_symbol_exists(tcgetattr "${CURL_INCLUDES}" HAVE_TCGETATTR)
|
||||||
@ -331,8 +304,8 @@ check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
|
|||||||
check_symbol_exists(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF)
|
check_symbol_exists(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF)
|
||||||
check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP)
|
check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP)
|
||||||
check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
|
check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
|
||||||
check_symbol_exists(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT)
|
#check_symbol_exists(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT)
|
||||||
check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
|
#check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
|
||||||
check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R)
|
check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R)
|
||||||
check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
|
check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
|
||||||
check_symbol_exists(usleep "${CURL_INCLUDES}" HAVE_USLEEP)
|
check_symbol_exists(usleep "${CURL_INCLUDES}" HAVE_USLEEP)
|
||||||
@ -340,17 +313,15 @@ check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME)
|
|||||||
check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R)
|
check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R)
|
||||||
check_symbol_exists(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
|
check_symbol_exists(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
|
||||||
|
|
||||||
check_symbol_exists(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME)
|
#check_symbol_exists(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME)
|
||||||
check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
|
check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
|
||||||
|
|
||||||
check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
|
check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
|
||||||
check_symbol_exists(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
|
check_symbol_exists(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
|
||||||
if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
|
set(HAVE_SIGNAL 1)
|
||||||
set(HAVE_SIGNAL 1)
|
|
||||||
endif()
|
|
||||||
check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
|
check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
|
||||||
check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL)
|
check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL)
|
||||||
check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64)
|
#check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64)
|
||||||
check_symbol_exists(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R)
|
check_symbol_exists(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R)
|
||||||
check_symbol_exists(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
|
check_symbol_exists(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
|
||||||
check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR)
|
check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR)
|
||||||
|
@ -129,9 +129,9 @@ public:
|
|||||||
|
|
||||||
void add(AggregateDataPtr place, const IColumn ** columns, const size_t row_num, Arena *) const override
|
void add(AggregateDataPtr place, const IColumn ** columns, const size_t row_num, Arena *) const override
|
||||||
{
|
{
|
||||||
/// TODO Inefficient.
|
/// NOTE Slightly inefficient.
|
||||||
const auto x = applyVisitor(FieldVisitorConvertToNumber<Float64>(), (*columns[0])[row_num]);
|
const auto x = columns[0]->getFloat64(row_num);
|
||||||
const auto y = applyVisitor(FieldVisitorConvertToNumber<Float64>(), (*columns[1])[row_num]);
|
const auto y = columns[1]->getFloat64(row_num);
|
||||||
data(place).add(x, y);
|
data(place).add(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ static IAggregateFunction * createAggregateFunctionArgMinMaxSecond(const DataTyp
|
|||||||
|
|
||||||
#define DISPATCH(TYPE) \
|
#define DISPATCH(TYPE) \
|
||||||
if (which.idx == TypeIndex::TYPE) \
|
if (which.idx == TypeIndex::TYPE) \
|
||||||
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<TYPE>>>>(res_type, val_type); \
|
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<TYPE>>>>(res_type, val_type);
|
||||||
FOR_NUMERIC_TYPES(DISPATCH)
|
FOR_NUMERIC_TYPES(DISPATCH)
|
||||||
#undef DISPATCH
|
#undef DISPATCH
|
||||||
|
|
||||||
|
@ -131,9 +131,7 @@ public:
|
|||||||
/** Contains a loop with calls to "add" function. You can collect arguments into array "places"
|
/** Contains a loop with calls to "add" function. You can collect arguments into array "places"
|
||||||
* and do a single call to "addBatch" for devirtualization and inlining.
|
* and do a single call to "addBatch" for devirtualization and inlining.
|
||||||
*/
|
*/
|
||||||
virtual void
|
virtual void addBatch(size_t batch_size, AggregateDataPtr * places, size_t place_offset, const IColumn ** columns, Arena * arena) const = 0;
|
||||||
addBatch(size_t batch_size, AggregateDataPtr * places, size_t place_offset, const IColumn ** columns, Arena * arena)
|
|
||||||
const = 0;
|
|
||||||
|
|
||||||
/** The same for single place.
|
/** The same for single place.
|
||||||
*/
|
*/
|
||||||
@ -144,9 +142,8 @@ public:
|
|||||||
* -Array combinator. It might also be used generally to break data dependency when array
|
* -Array combinator. It might also be used generally to break data dependency when array
|
||||||
* "places" contains a large number of same values consecutively.
|
* "places" contains a large number of same values consecutively.
|
||||||
*/
|
*/
|
||||||
virtual void
|
virtual void addBatchArray(
|
||||||
addBatchArray(size_t batch_size, AggregateDataPtr * places, size_t place_offset, const IColumn ** columns, const UInt64 * offsets, Arena * arena)
|
size_t batch_size, AggregateDataPtr * places, size_t place_offset, const IColumn ** columns, const UInt64 * offsets, Arena * arena) const = 0;
|
||||||
const = 0;
|
|
||||||
|
|
||||||
const DataTypes & getArgumentTypes() const { return argument_types; }
|
const DataTypes & getArgumentTypes() const { return argument_types; }
|
||||||
const Array & getParameters() const { return parameters; }
|
const Array & getParameters() const { return parameters; }
|
||||||
|
@ -23,12 +23,8 @@ namespace ErrorCodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
DatabaseDictionary::DatabaseDictionary(const String & name_)
|
DatabaseDictionary::DatabaseDictionary(const String & name_)
|
||||||
: name(name_),
|
: IDatabase(name_),
|
||||||
log(&Logger::get("DatabaseDictionary(" + name + ")"))
|
log(&Logger::get("DatabaseDictionary(" + database_name + ")"))
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDictionary::loadStoredObjects(Context &, bool)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,65 +65,6 @@ bool DatabaseDictionary::isTableExist(
|
|||||||
return context.getExternalDictionariesLoader().getCurrentStatus(table_name) != ExternalLoader::Status::NOT_EXIST;
|
return context.getExternalDictionariesLoader().getCurrentStatus(table_name) != ExternalLoader::Status::NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DatabaseDictionary::isDictionaryExist(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*table_name*/) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DatabaseDictionariesIteratorPtr DatabaseDictionary::getDictionariesIterator(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const FilterByNameFunction & /*filter_by_dictionary_name*/)
|
|
||||||
{
|
|
||||||
return std::make_unique<DatabaseDictionariesSnapshotIterator>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DatabaseDictionary::createDictionary(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*dictionary_name*/,
|
|
||||||
const ASTPtr & /*query*/)
|
|
||||||
{
|
|
||||||
throw Exception("Dictionary engine doesn't support dictionaries.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDictionary::removeDictionary(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*table_name*/)
|
|
||||||
{
|
|
||||||
throw Exception("Dictionary engine doesn't support dictionaries.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDictionary::attachDictionary(
|
|
||||||
const String & /*dictionary_name*/, const Context & /*context*/)
|
|
||||||
{
|
|
||||||
throw Exception("Dictionary engine doesn't support dictionaries.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDictionary::detachDictionary(const String & /*dictionary_name*/, const Context & /*context*/)
|
|
||||||
{
|
|
||||||
throw Exception("Dictionary engine doesn't support dictionaries.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASTPtr DatabaseDictionary::tryGetCreateDictionaryQuery(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*table_name*/) const
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASTPtr DatabaseDictionary::getCreateDictionaryQuery(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*table_name*/) const
|
|
||||||
{
|
|
||||||
throw Exception("Dictionary engine doesn't support dictionaries.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
StoragePtr DatabaseDictionary::tryGetTable(
|
StoragePtr DatabaseDictionary::tryGetTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) const
|
const String & table_name) const
|
||||||
@ -153,39 +90,6 @@ bool DatabaseDictionary::empty(const Context & context) const
|
|||||||
return !context.getExternalDictionariesLoader().hasCurrentlyLoadedObjects();
|
return !context.getExternalDictionariesLoader().hasCurrentlyLoadedObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePtr DatabaseDictionary::detachTable(const String & /*table_name*/)
|
|
||||||
{
|
|
||||||
throw Exception("DatabaseDictionary: detachTable() is not supported", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDictionary::attachTable(const String & /*table_name*/, const StoragePtr & /*table*/)
|
|
||||||
{
|
|
||||||
throw Exception("DatabaseDictionary: attachTable() is not supported", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDictionary::createTable(
|
|
||||||
const Context &,
|
|
||||||
const String &,
|
|
||||||
const StoragePtr &,
|
|
||||||
const ASTPtr &)
|
|
||||||
{
|
|
||||||
throw Exception("DatabaseDictionary: createTable() is not supported", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDictionary::removeTable(
|
|
||||||
const Context &,
|
|
||||||
const String &)
|
|
||||||
{
|
|
||||||
throw Exception("DatabaseDictionary: removeTable() is not supported", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t DatabaseDictionary::getObjectMetadataModificationTime(
|
|
||||||
const Context &,
|
|
||||||
const String &)
|
|
||||||
{
|
|
||||||
return static_cast<time_t>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseDictionary::getCreateTableQueryImpl(const Context & context,
|
ASTPtr DatabaseDictionary::getCreateTableQueryImpl(const Context & context,
|
||||||
const String & table_name, bool throw_on_error) const
|
const String & table_name, bool throw_on_error) const
|
||||||
{
|
{
|
||||||
@ -196,9 +100,11 @@ ASTPtr DatabaseDictionary::getCreateTableQueryImpl(const Context & context,
|
|||||||
const auto & dictionaries = context.getExternalDictionariesLoader();
|
const auto & dictionaries = context.getExternalDictionariesLoader();
|
||||||
auto dictionary = throw_on_error ? dictionaries.getDictionary(table_name)
|
auto dictionary = throw_on_error ? dictionaries.getDictionary(table_name)
|
||||||
: dictionaries.tryGetDictionary(table_name);
|
: dictionaries.tryGetDictionary(table_name);
|
||||||
|
if (!dictionary)
|
||||||
|
return {};
|
||||||
|
|
||||||
auto names_and_types = StorageDictionary::getNamesAndTypes(dictionary->getStructure());
|
auto names_and_types = StorageDictionary::getNamesAndTypes(dictionary->getStructure());
|
||||||
buffer << "CREATE TABLE " << backQuoteIfNeed(name) << '.' << backQuoteIfNeed(table_name) << " (";
|
buffer << "CREATE TABLE " << backQuoteIfNeed(database_name) << '.' << backQuoteIfNeed(table_name) << " (";
|
||||||
buffer << StorageDictionary::generateNamesAndTypesDescription(names_and_types.begin(), names_and_types.end());
|
buffer << StorageDictionary::generateNamesAndTypesDescription(names_and_types.begin(), names_and_types.end());
|
||||||
buffer << ") Engine = Dictionary(" << backQuoteIfNeed(table_name) << ")";
|
buffer << ") Engine = Dictionary(" << backQuoteIfNeed(table_name) << ")";
|
||||||
}
|
}
|
||||||
@ -215,22 +121,12 @@ ASTPtr DatabaseDictionary::getCreateTableQueryImpl(const Context & context,
|
|||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPtr DatabaseDictionary::getCreateTableQuery(const Context & context, const String & table_name) const
|
ASTPtr DatabaseDictionary::getCreateDatabaseQuery() const
|
||||||
{
|
|
||||||
return getCreateTableQueryImpl(context, table_name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseDictionary::tryGetCreateTableQuery(const Context & context, const String & table_name) const
|
|
||||||
{
|
|
||||||
return getCreateTableQueryImpl(context, table_name, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseDictionary::getCreateDatabaseQuery(const Context & /*context*/) const
|
|
||||||
{
|
{
|
||||||
String query;
|
String query;
|
||||||
{
|
{
|
||||||
WriteBufferFromString buffer(query);
|
WriteBufferFromString buffer(query);
|
||||||
buffer << "CREATE DATABASE " << backQuoteIfNeed(name) << " ENGINE = Dictionary";
|
buffer << "CREATE DATABASE " << backQuoteIfNeed(database_name) << " ENGINE = Dictionary";
|
||||||
}
|
}
|
||||||
ParserCreateQuery parser;
|
ParserCreateQuery parser;
|
||||||
return parseQuery(parser, query.data(), query.data() + query.size(), "", 0);
|
return parseQuery(parser, query.data(), query.data() + query.size(), "", 0);
|
||||||
@ -240,9 +136,4 @@ void DatabaseDictionary::shutdown()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
String DatabaseDictionary::getDatabaseName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,85 +24,36 @@ class DatabaseDictionary : public IDatabase
|
|||||||
public:
|
public:
|
||||||
DatabaseDictionary(const String & name_);
|
DatabaseDictionary(const String & name_);
|
||||||
|
|
||||||
String getDatabaseName() const override;
|
|
||||||
|
|
||||||
String getEngineName() const override
|
String getEngineName() const override
|
||||||
{
|
{
|
||||||
return "Dictionary";
|
return "Dictionary";
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadStoredObjects(
|
|
||||||
Context & context,
|
|
||||||
bool has_force_restore_data_flag) override;
|
|
||||||
|
|
||||||
bool isTableExist(
|
bool isTableExist(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) const override;
|
const String & table_name) const override;
|
||||||
|
|
||||||
bool isDictionaryExist(const Context & context, const String & table_name) const override;
|
|
||||||
|
|
||||||
StoragePtr tryGetTable(
|
StoragePtr tryGetTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) const override;
|
const String & table_name) const override;
|
||||||
|
|
||||||
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
||||||
|
|
||||||
DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name = {}) override;
|
|
||||||
|
|
||||||
bool empty(const Context & context) const override;
|
bool empty(const Context & context) const override;
|
||||||
|
|
||||||
void createTable(
|
ASTPtr getCreateDatabaseQuery() const override;
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
const StoragePtr & table,
|
|
||||||
const ASTPtr & query) override;
|
|
||||||
|
|
||||||
void createDictionary(
|
|
||||||
const Context & context, const String & dictionary_name, const ASTPtr & query) override;
|
|
||||||
|
|
||||||
void removeTable(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) override;
|
|
||||||
|
|
||||||
void removeDictionary(const Context & context, const String & table_name) override;
|
|
||||||
|
|
||||||
void attachTable(const String & table_name, const StoragePtr & table) override;
|
|
||||||
|
|
||||||
StoragePtr detachTable(const String & table_name) override;
|
|
||||||
|
|
||||||
time_t getObjectMetadataModificationTime(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) override;
|
|
||||||
|
|
||||||
ASTPtr getCreateTableQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) const override;
|
|
||||||
|
|
||||||
ASTPtr tryGetCreateTableQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) const override;
|
|
||||||
|
|
||||||
ASTPtr getCreateDatabaseQuery(const Context & context) const override;
|
|
||||||
|
|
||||||
ASTPtr getCreateDictionaryQuery(const Context & context, const String & table_name) const override;
|
|
||||||
|
|
||||||
ASTPtr tryGetCreateDictionaryQuery(const Context & context, const String & table_name) const override;
|
|
||||||
|
|
||||||
|
|
||||||
void attachDictionary(const String & dictionary_name, const Context & context) override;
|
|
||||||
|
|
||||||
void detachDictionary(const String & dictionary_name, const Context & context) override;
|
|
||||||
|
|
||||||
void shutdown() override;
|
void shutdown() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ASTPtr getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const String name;
|
|
||||||
mutable std::mutex mutex;
|
mutable std::mutex mutex;
|
||||||
|
|
||||||
Poco::Logger * log;
|
Poco::Logger * log;
|
||||||
|
|
||||||
Tables listTables(const Context & context, const FilterByNameFunction & filter_by_name);
|
Tables listTables(const Context & context, const FilterByNameFunction & filter_by_name);
|
||||||
ASTPtr getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <Databases/DatabaseOnDisk.h>
|
#include <Databases/DatabaseOnDisk.h>
|
||||||
#include <Databases/DatabasesCommon.h>
|
#include <Databases/DatabasesCommon.h>
|
||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <IO/ReadBufferFromFile.h>
|
|
||||||
#include <IO/ReadHelpers.h>
|
#include <IO/ReadHelpers.h>
|
||||||
#include <IO/WriteBufferFromFile.h>
|
#include <IO/WriteBufferFromFile.h>
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
@ -31,11 +30,8 @@ namespace ErrorCodes
|
|||||||
|
|
||||||
|
|
||||||
DatabaseLazy::DatabaseLazy(const String & name_, const String & metadata_path_, time_t expiration_time_, const Context & context_)
|
DatabaseLazy::DatabaseLazy(const String & name_, const String & metadata_path_, time_t expiration_time_, const Context & context_)
|
||||||
: name(name_)
|
: DatabaseOnDisk(name_, metadata_path_, "DatabaseLazy (" + name_ + ")")
|
||||||
, metadata_path(metadata_path_)
|
|
||||||
, data_path("data/" + escapeForFileName(name) + "/")
|
|
||||||
, expiration_time(expiration_time_)
|
, expiration_time(expiration_time_)
|
||||||
, log(&Logger::get("DatabaseLazy (" + name + ")"))
|
|
||||||
{
|
{
|
||||||
Poco::File(context_.getPath() + getDataPath()).createDirectories();
|
Poco::File(context_.getPath() + getDataPath()).createDirectories();
|
||||||
}
|
}
|
||||||
@ -45,7 +41,7 @@ void DatabaseLazy::loadStoredObjects(
|
|||||||
Context & context,
|
Context & context,
|
||||||
bool /* has_force_restore_data_flag */)
|
bool /* has_force_restore_data_flag */)
|
||||||
{
|
{
|
||||||
DatabaseOnDisk::iterateMetadataFiles(*this, log, context, [this](const String & file_name)
|
iterateMetadataFiles(context, [this](const String & file_name)
|
||||||
{
|
{
|
||||||
const std::string table_name = file_name.substr(0, file_name.size() - 4);
|
const std::string table_name = file_name.substr(0, file_name.size() - 4);
|
||||||
attachTable(table_name, nullptr);
|
attachTable(table_name, nullptr);
|
||||||
@ -62,75 +58,21 @@ void DatabaseLazy::createTable(
|
|||||||
SCOPE_EXIT({ clearExpiredTables(); });
|
SCOPE_EXIT({ clearExpiredTables(); });
|
||||||
if (!endsWith(table->getName(), "Log"))
|
if (!endsWith(table->getName(), "Log"))
|
||||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
||||||
DatabaseOnDisk::createTable(*this, context, table_name, table, query);
|
DatabaseOnDisk::createTable(context, table_name, table, query);
|
||||||
|
|
||||||
/// DatabaseOnDisk::createTable renames file, so we need to get new metadata_modification_time.
|
/// DatabaseOnDisk::createTable renames file, so we need to get new metadata_modification_time.
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
auto it = tables_cache.find(table_name);
|
auto it = tables_cache.find(table_name);
|
||||||
if (it != tables_cache.end())
|
if (it != tables_cache.end())
|
||||||
it->second.metadata_modification_time = DatabaseOnDisk::getObjectMetadataModificationTime(*this, table_name);
|
it->second.metadata_modification_time = DatabaseOnDisk::getObjectMetadataModificationTime(table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseLazy::createDictionary(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*dictionary_name*/,
|
|
||||||
const ASTPtr & /*query*/)
|
|
||||||
{
|
|
||||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DatabaseLazy::removeTable(
|
void DatabaseLazy::removeTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name)
|
const String & table_name)
|
||||||
{
|
{
|
||||||
SCOPE_EXIT({ clearExpiredTables(); });
|
SCOPE_EXIT({ clearExpiredTables(); });
|
||||||
DatabaseOnDisk::removeTable(*this, context, table_name, log);
|
DatabaseOnDisk::removeTable(context, table_name);
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseLazy::removeDictionary(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*table_name*/)
|
|
||||||
{
|
|
||||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseLazy::getCreateDictionaryQuery(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*table_name*/) const
|
|
||||||
{
|
|
||||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseLazy::tryGetCreateDictionaryQuery(const Context & /*context*/, const String & /*table_name*/) const
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseLazy::isDictionaryExist(const Context & /*context*/, const String & /*table_name*/) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DatabaseDictionariesIteratorPtr DatabaseLazy::getDictionariesIterator(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const FilterByNameFunction & /*filter_by_dictionary_name*/)
|
|
||||||
{
|
|
||||||
return std::make_unique<DatabaseDictionariesSnapshotIterator>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseLazy::attachDictionary(
|
|
||||||
const String & /*dictionary_name*/,
|
|
||||||
const Context & /*context*/)
|
|
||||||
{
|
|
||||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseLazy::detachDictionary(const String & /*dictionary_name*/, const Context & /*context*/)
|
|
||||||
{
|
|
||||||
throw Exception("Lazy engine can be used only with *Log tables.", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseLazy::renameTable(
|
void DatabaseLazy::renameTable(
|
||||||
@ -141,35 +83,17 @@ void DatabaseLazy::renameTable(
|
|||||||
TableStructureWriteLockHolder & lock)
|
TableStructureWriteLockHolder & lock)
|
||||||
{
|
{
|
||||||
SCOPE_EXIT({ clearExpiredTables(); });
|
SCOPE_EXIT({ clearExpiredTables(); });
|
||||||
DatabaseOnDisk::renameTable<DatabaseLazy>(*this, context, table_name, to_database, to_table_name, lock);
|
DatabaseOnDisk::renameTable(context, table_name, to_database, to_table_name, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
time_t DatabaseLazy::getObjectMetadataModificationTime(
|
time_t DatabaseLazy::getObjectMetadataModificationTime(const String & table_name) const
|
||||||
const Context & /* context */,
|
|
||||||
const String & table_name)
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
auto it = tables_cache.find(table_name);
|
auto it = tables_cache.find(table_name);
|
||||||
if (it != tables_cache.end())
|
if (it != tables_cache.end())
|
||||||
return it->second.metadata_modification_time;
|
return it->second.metadata_modification_time;
|
||||||
else
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseLazy::getCreateTableQuery(const Context & context, const String & table_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getCreateTableQuery(*this, context, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseLazy::tryGetCreateTableQuery(const Context & context, const String & table_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::tryGetCreateTableQuery(*this, context, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseLazy::getCreateDatabaseQuery(const Context & context) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getCreateDatabaseQuery(*this, context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseLazy::alterTable(
|
void DatabaseLazy::alterTable(
|
||||||
@ -177,22 +101,16 @@ void DatabaseLazy::alterTable(
|
|||||||
const String & /* table_name */,
|
const String & /* table_name */,
|
||||||
const StorageInMemoryMetadata & /* metadata */)
|
const StorageInMemoryMetadata & /* metadata */)
|
||||||
{
|
{
|
||||||
SCOPE_EXIT({ clearExpiredTables(); });
|
clearExpiredTables();
|
||||||
throw Exception("ALTER query is not supported for Lazy database.", ErrorCodes::UNSUPPORTED_METHOD);
|
throw Exception("ALTER query is not supported for Lazy database.", ErrorCodes::UNSUPPORTED_METHOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseLazy::drop(const Context & context)
|
|
||||||
{
|
|
||||||
DatabaseOnDisk::drop(*this, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseLazy::isTableExist(
|
bool DatabaseLazy::isTableExist(
|
||||||
const Context & /* context */,
|
const Context & /* context */,
|
||||||
const String & table_name) const
|
const String & table_name) const
|
||||||
{
|
{
|
||||||
SCOPE_EXIT({ clearExpiredTables(); });
|
SCOPE_EXIT({ clearExpiredTables(); });
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
return tables_cache.find(table_name) != tables_cache.end();
|
return tables_cache.find(table_name) != tables_cache.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +120,7 @@ StoragePtr DatabaseLazy::tryGetTable(
|
|||||||
{
|
{
|
||||||
SCOPE_EXIT({ clearExpiredTables(); });
|
SCOPE_EXIT({ clearExpiredTables(); });
|
||||||
{
|
{
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
auto it = tables_cache.find(table_name);
|
auto it = tables_cache.find(table_name);
|
||||||
if (it == tables_cache.end())
|
if (it == tables_cache.end())
|
||||||
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
@ -222,7 +140,7 @@ StoragePtr DatabaseLazy::tryGetTable(
|
|||||||
|
|
||||||
DatabaseTablesIteratorPtr DatabaseLazy::getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name)
|
DatabaseTablesIteratorPtr DatabaseLazy::getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
Strings filtered_tables;
|
Strings filtered_tables;
|
||||||
for (const auto & [table_name, cached_table] : tables_cache)
|
for (const auto & [table_name, cached_table] : tables_cache)
|
||||||
{
|
{
|
||||||
@ -241,12 +159,12 @@ bool DatabaseLazy::empty(const Context & /* context */) const
|
|||||||
void DatabaseLazy::attachTable(const String & table_name, const StoragePtr & table)
|
void DatabaseLazy::attachTable(const String & table_name, const StoragePtr & table)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(log, "Attach table " << backQuote(table_name) << ".");
|
LOG_DEBUG(log, "Attach table " << backQuote(table_name) << ".");
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
time_t current_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
time_t current_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||||
|
|
||||||
auto [it, inserted] = tables_cache.emplace(std::piecewise_construct,
|
auto [it, inserted] = tables_cache.emplace(std::piecewise_construct,
|
||||||
std::forward_as_tuple(table_name),
|
std::forward_as_tuple(table_name),
|
||||||
std::forward_as_tuple(table, current_time, DatabaseOnDisk::getObjectMetadataModificationTime(*this, table_name)));
|
std::forward_as_tuple(table, current_time, DatabaseOnDisk::getObjectMetadataModificationTime(table_name)));
|
||||||
if (!inserted)
|
if (!inserted)
|
||||||
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
||||||
|
|
||||||
@ -258,7 +176,7 @@ StoragePtr DatabaseLazy::detachTable(const String & table_name)
|
|||||||
StoragePtr res;
|
StoragePtr res;
|
||||||
{
|
{
|
||||||
LOG_DEBUG(log, "Detach table " << backQuote(table_name) << ".");
|
LOG_DEBUG(log, "Detach table " << backQuote(table_name) << ".");
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
auto it = tables_cache.find(table_name);
|
auto it = tables_cache.find(table_name);
|
||||||
if (it == tables_cache.end())
|
if (it == tables_cache.end())
|
||||||
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
@ -274,7 +192,7 @@ void DatabaseLazy::shutdown()
|
|||||||
{
|
{
|
||||||
TablesCache tables_snapshot;
|
TablesCache tables_snapshot;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
tables_snapshot = tables_cache;
|
tables_snapshot = tables_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +202,7 @@ void DatabaseLazy::shutdown()
|
|||||||
kv.second.table->shutdown();
|
kv.second.table->shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
tables_cache.clear();
|
tables_cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,26 +218,6 @@ DatabaseLazy::~DatabaseLazy()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String DatabaseLazy::getDataPath() const
|
|
||||||
{
|
|
||||||
return data_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
String DatabaseLazy::getMetadataPath() const
|
|
||||||
{
|
|
||||||
return metadata_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
String DatabaseLazy::getDatabaseName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
String DatabaseLazy::getObjectMetadataPath(const String & table_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getObjectMetadataPath(*this, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
StoragePtr DatabaseLazy::loadTable(const Context & context, const String & table_name) const
|
StoragePtr DatabaseLazy::loadTable(const Context & context, const String & table_name) const
|
||||||
{
|
{
|
||||||
SCOPE_EXIT({ clearExpiredTables(); });
|
SCOPE_EXIT({ clearExpiredTables(); });
|
||||||
@ -330,19 +228,21 @@ StoragePtr DatabaseLazy::loadTable(const Context & context, const String & table
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String table_name_;
|
|
||||||
StoragePtr table;
|
StoragePtr table;
|
||||||
Context context_copy(context); /// some tables can change context, but not LogTables
|
Context context_copy(context); /// some tables can change context, but not LogTables
|
||||||
|
|
||||||
auto ast = parseCreateQueryFromMetadataFile(table_metadata_path, log);
|
auto ast = parseQueryFromMetadata(table_metadata_path, /*throw_on_error*/ true, /*remove_empty*/false);
|
||||||
if (ast)
|
if (ast)
|
||||||
std::tie(table_name_, table) = createTableFromAST(
|
{
|
||||||
ast->as<const ASTCreateQuery &>(), name, getDataPath(), context_copy, false);
|
auto & ast_create = ast->as<const ASTCreateQuery &>();
|
||||||
|
String table_data_path_relative = getTableDataPath(ast_create);
|
||||||
|
table = createTableFromAST(ast_create, database_name, table_data_path_relative, context_copy, false).second;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ast || !endsWith(table->getName(), "Log"))
|
if (!ast || !endsWith(table->getName(), "Log"))
|
||||||
throw Exception("Only *Log tables can be used with Lazy database engine.", ErrorCodes::LOGICAL_ERROR);
|
throw Exception("Only *Log tables can be used with Lazy database engine.", ErrorCodes::LOGICAL_ERROR);
|
||||||
{
|
{
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
auto it = tables_cache.find(table_name);
|
auto it = tables_cache.find(table_name);
|
||||||
if (it == tables_cache.end())
|
if (it == tables_cache.end())
|
||||||
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
@ -364,7 +264,7 @@ StoragePtr DatabaseLazy::loadTable(const Context & context, const String & table
|
|||||||
|
|
||||||
void DatabaseLazy::clearExpiredTables() const
|
void DatabaseLazy::clearExpiredTables() const
|
||||||
{
|
{
|
||||||
std::lock_guard lock(tables_mutex);
|
std::lock_guard lock(mutex);
|
||||||
auto time_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
auto time_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||||
|
|
||||||
CacheExpirationQueue expired_tables;
|
CacheExpirationQueue expired_tables;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Databases/DatabasesCommon.h>
|
#include <Databases/DatabaseOnDisk.h>
|
||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <Parsers/ASTCreateQuery.h>
|
#include <Parsers/ASTCreateQuery.h>
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ class DatabaseLazyIterator;
|
|||||||
* Works like DatabaseOrdinary, but stores in memory only cache.
|
* Works like DatabaseOrdinary, but stores in memory only cache.
|
||||||
* Can be used only with *Log engines.
|
* Can be used only with *Log engines.
|
||||||
*/
|
*/
|
||||||
class DatabaseLazy : public IDatabase
|
class DatabaseLazy : public DatabaseOnDisk
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DatabaseLazy(const String & name_, const String & metadata_path_, time_t expiration_time_, const Context & context_);
|
DatabaseLazy(const String & name_, const String & metadata_path_, time_t expiration_time_, const Context & context_);
|
||||||
@ -32,19 +32,10 @@ public:
|
|||||||
const StoragePtr & table,
|
const StoragePtr & table,
|
||||||
const ASTPtr & query) override;
|
const ASTPtr & query) override;
|
||||||
|
|
||||||
void createDictionary(
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
const ASTPtr & query) override;
|
|
||||||
|
|
||||||
void removeTable(
|
void removeTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) override;
|
const String & table_name) override;
|
||||||
|
|
||||||
void removeDictionary(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) override;
|
|
||||||
|
|
||||||
void renameTable(
|
void renameTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
@ -57,43 +48,12 @@ public:
|
|||||||
const String & name,
|
const String & name,
|
||||||
const StorageInMemoryMetadata & metadata) override;
|
const StorageInMemoryMetadata & metadata) override;
|
||||||
|
|
||||||
time_t getObjectMetadataModificationTime(
|
time_t getObjectMetadataModificationTime(const String & table_name) const override;
|
||||||
const Context & context,
|
|
||||||
const String & table_name) override;
|
|
||||||
|
|
||||||
ASTPtr getCreateTableQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) const override;
|
|
||||||
|
|
||||||
ASTPtr tryGetCreateTableQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) const override;
|
|
||||||
|
|
||||||
ASTPtr getCreateDictionaryQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name) const override;
|
|
||||||
|
|
||||||
ASTPtr tryGetCreateDictionaryQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name) const override;
|
|
||||||
|
|
||||||
ASTPtr getCreateDatabaseQuery(const Context & context) const override;
|
|
||||||
|
|
||||||
String getDataPath() const override;
|
|
||||||
String getDatabaseName() const override;
|
|
||||||
String getMetadataPath() const override;
|
|
||||||
String getObjectMetadataPath(const String & table_name) const override;
|
|
||||||
|
|
||||||
void drop(const Context & context) override;
|
|
||||||
|
|
||||||
bool isTableExist(
|
bool isTableExist(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) const override;
|
const String & table_name) const override;
|
||||||
|
|
||||||
bool isDictionaryExist(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) const override;
|
|
||||||
|
|
||||||
StoragePtr tryGetTable(
|
StoragePtr tryGetTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) const override;
|
const String & table_name) const override;
|
||||||
@ -102,16 +62,10 @@ public:
|
|||||||
|
|
||||||
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
||||||
|
|
||||||
DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name = {}) override;
|
|
||||||
|
|
||||||
void attachTable(const String & table_name, const StoragePtr & table) override;
|
void attachTable(const String & table_name, const StoragePtr & table) override;
|
||||||
|
|
||||||
StoragePtr detachTable(const String & table_name) override;
|
StoragePtr detachTable(const String & table_name) override;
|
||||||
|
|
||||||
void attachDictionary(const String & dictionary_name, const Context & context) override;
|
|
||||||
|
|
||||||
void detachDictionary(const String & dictionary_name, const Context & context) override;
|
|
||||||
|
|
||||||
void shutdown() override;
|
void shutdown() override;
|
||||||
|
|
||||||
~DatabaseLazy() override;
|
~DatabaseLazy() override;
|
||||||
@ -143,19 +97,12 @@ private:
|
|||||||
|
|
||||||
using TablesCache = std::unordered_map<String, CachedTable>;
|
using TablesCache = std::unordered_map<String, CachedTable>;
|
||||||
|
|
||||||
|
|
||||||
String name;
|
|
||||||
const String metadata_path;
|
|
||||||
const String data_path;
|
|
||||||
|
|
||||||
const time_t expiration_time;
|
const time_t expiration_time;
|
||||||
|
|
||||||
mutable std::mutex tables_mutex;
|
/// TODO use DatabaseWithOwnTablesBase::tables
|
||||||
mutable TablesCache tables_cache;
|
mutable TablesCache tables_cache;
|
||||||
mutable CacheExpirationQueue cache_expiration_queue;
|
mutable CacheExpirationQueue cache_expiration_queue;
|
||||||
|
|
||||||
Poco::Logger * log;
|
|
||||||
|
|
||||||
StoragePtr loadTable(const Context & context, const String & table_name) const;
|
StoragePtr loadTable(const Context & context, const String & table_name) const;
|
||||||
|
|
||||||
void clearExpiredTables() const;
|
void clearExpiredTables() const;
|
||||||
|
@ -1,30 +1,16 @@
|
|||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
#include <Databases/DatabaseMemory.h>
|
#include <Databases/DatabaseMemory.h>
|
||||||
#include <Databases/DatabasesCommon.h>
|
#include <Databases/DatabasesCommon.h>
|
||||||
|
#include <Parsers/ASTCreateQuery.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace ErrorCodes
|
DatabaseMemory::DatabaseMemory(const String & name_)
|
||||||
{
|
: DatabaseWithOwnTablesBase(name_, "DatabaseMemory(" + name_ + ")")
|
||||||
extern const int CANNOT_GET_CREATE_TABLE_QUERY;
|
|
||||||
extern const int CANNOT_GET_CREATE_DICTIONARY_QUERY;
|
|
||||||
extern const int UNSUPPORTED_METHOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
DatabaseMemory::DatabaseMemory(String name_)
|
|
||||||
: DatabaseWithOwnTablesBase(std::move(name_))
|
|
||||||
, log(&Logger::get("DatabaseMemory(" + name + ")"))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void DatabaseMemory::loadStoredObjects(
|
|
||||||
Context & /*context*/,
|
|
||||||
bool /*has_force_restore_data_flag*/)
|
|
||||||
{
|
|
||||||
/// Nothing to load.
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseMemory::createTable(
|
void DatabaseMemory::createTable(
|
||||||
const Context & /*context*/,
|
const Context & /*context*/,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
@ -34,21 +20,6 @@ void DatabaseMemory::createTable(
|
|||||||
attachTable(table_name, table);
|
attachTable(table_name, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseMemory::attachDictionary(const String & /*name*/, const Context & /*context*/)
|
|
||||||
{
|
|
||||||
throw Exception("There is no ATTACH DICTIONARY query for DatabaseMemory", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseMemory::createDictionary(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*dictionary_name*/,
|
|
||||||
const ASTPtr & /*query*/)
|
|
||||||
{
|
|
||||||
throw Exception("There is no CREATE DICTIONARY query for DatabaseMemory", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DatabaseMemory::removeTable(
|
void DatabaseMemory::removeTable(
|
||||||
const Context & /*context*/,
|
const Context & /*context*/,
|
||||||
const String & table_name)
|
const String & table_name)
|
||||||
@ -56,52 +27,13 @@ void DatabaseMemory::removeTable(
|
|||||||
detachTable(table_name);
|
detachTable(table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTPtr DatabaseMemory::getCreateDatabaseQuery() const
|
||||||
void DatabaseMemory::detachDictionary(const String & /*name*/, const Context & /*context*/)
|
|
||||||
{
|
{
|
||||||
throw Exception("There is no DETACH DICTIONARY query for DatabaseMemory", ErrorCodes::UNSUPPORTED_METHOD);
|
auto create_query = std::make_shared<ASTCreateQuery>();
|
||||||
}
|
create_query->database = database_name;
|
||||||
|
create_query->set(create_query->storage, std::make_shared<ASTStorage>());
|
||||||
|
create_query->storage->set(create_query->storage->engine, makeASTFunction(getEngineName()));
|
||||||
void DatabaseMemory::removeDictionary(
|
return create_query;
|
||||||
const Context & /*context*/,
|
|
||||||
const String & /*dictionary_name*/)
|
|
||||||
{
|
|
||||||
throw Exception("There is no DROP DICTIONARY query for DatabaseMemory", ErrorCodes::UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
time_t DatabaseMemory::getObjectMetadataModificationTime(
|
|
||||||
const Context &, const String &)
|
|
||||||
{
|
|
||||||
return static_cast<time_t>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseMemory::getCreateTableQuery(
|
|
||||||
const Context &,
|
|
||||||
const String &) const
|
|
||||||
{
|
|
||||||
throw Exception("There is no CREATE TABLE query for DatabaseMemory tables", ErrorCodes::CANNOT_GET_CREATE_TABLE_QUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASTPtr DatabaseMemory::getCreateDictionaryQuery(
|
|
||||||
const Context &,
|
|
||||||
const String &) const
|
|
||||||
{
|
|
||||||
throw Exception("There is no CREATE DICTIONARY query for DatabaseMemory dictionaries", ErrorCodes::CANNOT_GET_CREATE_DICTIONARY_QUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASTPtr DatabaseMemory::getCreateDatabaseQuery(
|
|
||||||
const Context &) const
|
|
||||||
{
|
|
||||||
throw Exception("There is no CREATE DATABASE query for DatabaseMemory", ErrorCodes::CANNOT_GET_CREATE_TABLE_QUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
String DatabaseMemory::getDatabaseName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,54 +17,21 @@ namespace DB
|
|||||||
class DatabaseMemory : public DatabaseWithOwnTablesBase
|
class DatabaseMemory : public DatabaseWithOwnTablesBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DatabaseMemory(String name_);
|
DatabaseMemory(const String & name_);
|
||||||
|
|
||||||
String getDatabaseName() const override;
|
|
||||||
|
|
||||||
String getEngineName() const override { return "Memory"; }
|
String getEngineName() const override { return "Memory"; }
|
||||||
|
|
||||||
void loadStoredObjects(
|
|
||||||
Context & context,
|
|
||||||
bool has_force_restore_data_flag) override;
|
|
||||||
|
|
||||||
void createTable(
|
void createTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
const StoragePtr & table,
|
const StoragePtr & table,
|
||||||
const ASTPtr & query) override;
|
const ASTPtr & query) override;
|
||||||
|
|
||||||
void createDictionary(
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
const ASTPtr & query) override;
|
|
||||||
|
|
||||||
void attachDictionary(
|
|
||||||
const String & name,
|
|
||||||
const Context & context) override;
|
|
||||||
|
|
||||||
void removeTable(
|
void removeTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) override;
|
const String & table_name) override;
|
||||||
|
|
||||||
void removeDictionary(
|
ASTPtr getCreateDatabaseQuery() const override;
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name) override;
|
|
||||||
|
|
||||||
void detachDictionary(
|
|
||||||
const String & name,
|
|
||||||
const Context & context) override;
|
|
||||||
|
|
||||||
time_t getObjectMetadataModificationTime(const Context & context, const String & table_name) override;
|
|
||||||
|
|
||||||
ASTPtr getCreateTableQuery(const Context & context, const String & table_name) const override;
|
|
||||||
ASTPtr getCreateDictionaryQuery(const Context & context, const String & table_name) const override;
|
|
||||||
ASTPtr tryGetCreateTableQuery(const Context &, const String &) const override { return nullptr; }
|
|
||||||
ASTPtr tryGetCreateDictionaryQuery(const Context &, const String &) const override { return nullptr; }
|
|
||||||
|
|
||||||
ASTPtr getCreateDatabaseQuery(const Context & context) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Poco::Logger * log;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,8 @@
|
|||||||
#include <Formats/MySQLBlockInputStream.h>
|
#include <Formats/MySQLBlockInputStream.h>
|
||||||
#include <DataTypes/DataTypeString.h>
|
#include <DataTypes/DataTypeString.h>
|
||||||
#include <DataTypes/DataTypesNumber.h>
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
#include <DataTypes/DataTypeDate.h>
|
|
||||||
#include <DataTypes/DataTypeDateTime.h>
|
#include <DataTypes/DataTypeDateTime.h>
|
||||||
#include <DataTypes/DataTypeNullable.h>
|
#include <DataTypes/DataTypeNullable.h>
|
||||||
#include <DataTypes/DataTypeFixedString.h>
|
|
||||||
#include <Storages/StorageMySQL.h>
|
#include <Storages/StorageMySQL.h>
|
||||||
#include <Parsers/ASTFunction.h>
|
#include <Parsers/ASTFunction.h>
|
||||||
#include <Parsers/ParserCreateQuery.h>
|
#include <Parsers/ParserCreateQuery.h>
|
||||||
@ -63,8 +61,12 @@ static String toQueryStringWithQuote(const std::vector<String> & quote_list)
|
|||||||
DatabaseMySQL::DatabaseMySQL(
|
DatabaseMySQL::DatabaseMySQL(
|
||||||
const Context & global_context_, const String & database_name_, const String & metadata_path_,
|
const Context & global_context_, const String & database_name_, const String & metadata_path_,
|
||||||
const ASTStorage * database_engine_define_, const String & database_name_in_mysql_, mysqlxx::Pool && pool)
|
const ASTStorage * database_engine_define_, const String & database_name_in_mysql_, mysqlxx::Pool && pool)
|
||||||
: global_context(global_context_), database_name(database_name_), metadata_path(metadata_path_),
|
: IDatabase(database_name_)
|
||||||
database_engine_define(database_engine_define_->clone()), database_name_in_mysql(database_name_in_mysql_), mysql_pool(std::move(pool))
|
, global_context(global_context_)
|
||||||
|
, metadata_path(metadata_path_)
|
||||||
|
, database_engine_define(database_engine_define_->clone())
|
||||||
|
, database_name_in_mysql(database_name_in_mysql_)
|
||||||
|
, mysql_pool(std::move(pool))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,19 +152,24 @@ static ASTPtr getCreateQueryFromStorage(const StoragePtr & storage, const ASTPtr
|
|||||||
return create_table_query;
|
return create_table_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPtr DatabaseMySQL::tryGetCreateTableQuery(const Context &, const String & table_name) const
|
ASTPtr DatabaseMySQL::getCreateTableQueryImpl(const Context &, const String & table_name, bool throw_on_error) const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
fetchTablesIntoLocalCache();
|
fetchTablesIntoLocalCache();
|
||||||
|
|
||||||
if (local_tables_cache.find(table_name) == local_tables_cache.end())
|
if (local_tables_cache.find(table_name) == local_tables_cache.end())
|
||||||
throw Exception("MySQL table " + database_name_in_mysql + "." + table_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
{
|
||||||
|
if (throw_on_error)
|
||||||
|
throw Exception("MySQL table " + database_name_in_mysql + "." + table_name + " doesn't exist..",
|
||||||
|
ErrorCodes::UNKNOWN_TABLE);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return getCreateQueryFromStorage(local_tables_cache[table_name].second, database_engine_define);
|
return getCreateQueryFromStorage(local_tables_cache[table_name].second, database_engine_define);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t DatabaseMySQL::getObjectMetadataModificationTime(const Context &, const String & table_name)
|
time_t DatabaseMySQL::getObjectMetadataModificationTime(const String & table_name) const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
@ -174,7 +181,7 @@ time_t DatabaseMySQL::getObjectMetadataModificationTime(const Context &, const S
|
|||||||
return time_t(local_tables_cache[table_name].first);
|
return time_t(local_tables_cache[table_name].first);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPtr DatabaseMySQL::getCreateDatabaseQuery(const Context &) const
|
ASTPtr DatabaseMySQL::getCreateDatabaseQuery() const
|
||||||
{
|
{
|
||||||
const auto & create_query = std::make_shared<ASTCreateQuery>();
|
const auto & create_query = std::make_shared<ASTCreateQuery>();
|
||||||
create_query->database = database_name;
|
create_query->database = database_name;
|
||||||
|
@ -28,35 +28,17 @@ public:
|
|||||||
|
|
||||||
String getEngineName() const override { return "MySQL"; }
|
String getEngineName() const override { return "MySQL"; }
|
||||||
|
|
||||||
String getDatabaseName() const override { return database_name; }
|
|
||||||
|
|
||||||
bool empty(const Context & context) const override;
|
bool empty(const Context & context) const override;
|
||||||
|
|
||||||
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
||||||
|
|
||||||
DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context &, const FilterByNameFunction & = {}) override
|
ASTPtr getCreateDatabaseQuery() const override;
|
||||||
{
|
|
||||||
return std::make_unique<DatabaseDictionariesSnapshotIterator>();
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr getCreateDatabaseQuery(const Context & context) const override;
|
|
||||||
|
|
||||||
bool isTableExist(const Context & context, const String & name) const override;
|
bool isTableExist(const Context & context, const String & name) const override;
|
||||||
|
|
||||||
bool isDictionaryExist(const Context &, const String &) const override { return false; }
|
|
||||||
|
|
||||||
StoragePtr tryGetTable(const Context & context, const String & name) const override;
|
StoragePtr tryGetTable(const Context & context, const String & name) const override;
|
||||||
|
|
||||||
ASTPtr tryGetCreateTableQuery(const Context & context, const String & name) const override;
|
time_t getObjectMetadataModificationTime(const String & name) const override;
|
||||||
|
|
||||||
ASTPtr getCreateDictionaryQuery(const Context &, const String &) const override
|
|
||||||
{
|
|
||||||
throw Exception("MySQL database engine does not support dictionaries.", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr tryGetCreateDictionaryQuery(const Context &, const String &) const override { return nullptr; }
|
|
||||||
|
|
||||||
time_t getObjectMetadataModificationTime(const Context & context, const String & name) override;
|
|
||||||
|
|
||||||
void shutdown() override;
|
void shutdown() override;
|
||||||
|
|
||||||
@ -74,29 +56,12 @@ public:
|
|||||||
|
|
||||||
void attachTable(const String & table_name, const StoragePtr & storage) override;
|
void attachTable(const String & table_name, const StoragePtr & storage) override;
|
||||||
|
|
||||||
void detachDictionary(const String &, const Context &) override
|
|
||||||
{
|
|
||||||
throw Exception("MySQL database engine does not support detach dictionary.", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeDictionary(const Context &, const String &) override
|
protected:
|
||||||
{
|
ASTPtr getCreateTableQueryImpl(const Context & context, const String & name, bool throw_on_error) const override;
|
||||||
throw Exception("MySQL database engine does not support remove dictionary.", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachDictionary(const String &, const Context &) override
|
|
||||||
{
|
|
||||||
throw Exception("MySQL database engine does not support attach dictionary.", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void createDictionary(const Context &, const String &, const ASTPtr &) override
|
|
||||||
{
|
|
||||||
throw Exception("MySQL database engine does not support create dictionary.", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Context global_context;
|
Context global_context;
|
||||||
String database_name;
|
|
||||||
String metadata_path;
|
String metadata_path;
|
||||||
ASTPtr database_engine_define;
|
ASTPtr database_engine_define;
|
||||||
String database_name_in_mysql;
|
String database_name_in_mysql;
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <Interpreters/InterpreterCreateQuery.h>
|
#include <Interpreters/InterpreterCreateQuery.h>
|
||||||
#include <Interpreters/ExternalDictionariesLoader.h>
|
|
||||||
#include <Interpreters/ExternalLoaderPresetConfigRepository.h>
|
|
||||||
#include <Dictionaries/getDictionaryConfigurationFromAST.h>
|
|
||||||
#include <Parsers/ASTCreateQuery.h>
|
#include <Parsers/ASTCreateQuery.h>
|
||||||
#include <Parsers/ParserCreateQuery.h>
|
#include <Parsers/ParserCreateQuery.h>
|
||||||
#include <Parsers/formatAST.h>
|
#include <Parsers/formatAST.h>
|
||||||
@ -19,7 +16,6 @@
|
|||||||
#include <Common/escapeForFileName.h>
|
#include <Common/escapeForFileName.h>
|
||||||
|
|
||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
#include <ext/scope_guard.h>
|
|
||||||
#include <Poco/DirectoryIterator.h>
|
#include <Poco/DirectoryIterator.h>
|
||||||
|
|
||||||
|
|
||||||
@ -31,8 +27,6 @@ static constexpr size_t METADATA_FILE_BUFFER_SIZE = 32768;
|
|||||||
|
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
extern const int CANNOT_GET_CREATE_TABLE_QUERY;
|
|
||||||
extern const int CANNOT_GET_CREATE_DICTIONARY_QUERY;
|
|
||||||
extern const int FILE_DOESNT_EXIST;
|
extern const int FILE_DOESNT_EXIST;
|
||||||
extern const int INCORRECT_FILE_NAME;
|
extern const int INCORRECT_FILE_NAME;
|
||||||
extern const int SYNTAX_ERROR;
|
extern const int SYNTAX_ERROR;
|
||||||
@ -43,93 +37,10 @@ namespace ErrorCodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
String getObjectMetadataPath(const String & base_path, const String & table_name)
|
|
||||||
{
|
|
||||||
return base_path + (endsWith(base_path, "/") ? "" : "/") + escapeForFileName(table_name) + ".sql";
|
|
||||||
}
|
|
||||||
|
|
||||||
String getDatabaseMetadataPath(const String & base_path)
|
|
||||||
{
|
|
||||||
return (endsWith(base_path, "/") ? base_path.substr(0, base_path.size() - 1) : base_path) + ".sql";
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr getQueryFromMetadata(const String & metadata_path, bool throw_on_error)
|
|
||||||
{
|
|
||||||
String query;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ReadBufferFromFile in(metadata_path, 4096);
|
|
||||||
readStringUntilEOF(query, in);
|
|
||||||
}
|
|
||||||
catch (const Exception & e)
|
|
||||||
{
|
|
||||||
if (!throw_on_error && e.code() == ErrorCodes::FILE_DOESNT_EXIST)
|
|
||||||
return nullptr;
|
|
||||||
else
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParserCreateQuery parser;
|
|
||||||
const char * pos = query.data();
|
|
||||||
std::string error_message;
|
|
||||||
auto ast = tryParseQuery(parser, pos, pos + query.size(), error_message, /* hilite = */ false,
|
|
||||||
"in file " + metadata_path, /* allow_multi_statements = */ false, 0);
|
|
||||||
|
|
||||||
if (!ast && throw_on_error)
|
|
||||||
throw Exception(error_message, ErrorCodes::SYNTAX_ERROR);
|
|
||||||
|
|
||||||
return ast;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr getCreateQueryFromMetadata(const String & metadata_path, const String & database, bool throw_on_error)
|
|
||||||
{
|
|
||||||
ASTPtr ast = getQueryFromMetadata(metadata_path, throw_on_error);
|
|
||||||
|
|
||||||
if (ast)
|
|
||||||
{
|
|
||||||
auto & ast_create_query = ast->as<ASTCreateQuery &>();
|
|
||||||
ast_create_query.attach = false;
|
|
||||||
ast_create_query.database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASTPtr parseCreateQueryFromMetadataFile(const String & filepath, Poco::Logger * log)
|
|
||||||
{
|
|
||||||
String definition;
|
|
||||||
{
|
|
||||||
char in_buf[METADATA_FILE_BUFFER_SIZE];
|
|
||||||
ReadBufferFromFile in(filepath, METADATA_FILE_BUFFER_SIZE, -1, in_buf);
|
|
||||||
readStringUntilEOF(definition, in);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Empty files with metadata are generated after a rough restart of the server.
|
|
||||||
* Remove these files to slightly reduce the work of the admins on startup.
|
|
||||||
*/
|
|
||||||
if (definition.empty())
|
|
||||||
{
|
|
||||||
LOG_ERROR(log, "File " << filepath << " is empty. Removing.");
|
|
||||||
Poco::File(filepath).remove();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParserCreateQuery parser_create;
|
|
||||||
ASTPtr result = parseQuery(parser_create, definition, "in file " + filepath, 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::pair<String, StoragePtr> createTableFromAST(
|
std::pair<String, StoragePtr> createTableFromAST(
|
||||||
ASTCreateQuery ast_create_query,
|
ASTCreateQuery ast_create_query,
|
||||||
const String & database_name,
|
const String & database_name,
|
||||||
const String & database_data_path_relative,
|
const String & table_data_path_relative,
|
||||||
Context & context,
|
Context & context,
|
||||||
bool has_force_restore_data_flag)
|
bool has_force_restore_data_flag)
|
||||||
{
|
{
|
||||||
@ -144,7 +55,7 @@ std::pair<String, StoragePtr> createTableFromAST(
|
|||||||
return {ast_create_query.table, storage};
|
return {ast_create_query.table, storage};
|
||||||
}
|
}
|
||||||
/// We do not directly use `InterpreterCreateQuery::execute`, because
|
/// We do not directly use `InterpreterCreateQuery::execute`, because
|
||||||
/// - the database has not been created yet;
|
/// - the database has not been loaded yet;
|
||||||
/// - the code is simpler, since the query is already brought to a suitable form.
|
/// - the code is simpler, since the query is already brought to a suitable form.
|
||||||
if (!ast_create_query.columns_list || !ast_create_query.columns_list->columns)
|
if (!ast_create_query.columns_list || !ast_create_query.columns_list->columns)
|
||||||
throw Exception("Missing definition of columns.", ErrorCodes::EMPTY_LIST_OF_COLUMNS_PASSED);
|
throw Exception("Missing definition of columns.", ErrorCodes::EMPTY_LIST_OF_COLUMNS_PASSED);
|
||||||
@ -152,7 +63,6 @@ std::pair<String, StoragePtr> createTableFromAST(
|
|||||||
ColumnsDescription columns = InterpreterCreateQuery::getColumnsDescription(*ast_create_query.columns_list->columns, context);
|
ColumnsDescription columns = InterpreterCreateQuery::getColumnsDescription(*ast_create_query.columns_list->columns, context);
|
||||||
ConstraintsDescription constraints = InterpreterCreateQuery::getConstraintsDescription(ast_create_query.columns_list->constraints);
|
ConstraintsDescription constraints = InterpreterCreateQuery::getConstraintsDescription(ast_create_query.columns_list->constraints);
|
||||||
|
|
||||||
String table_data_path_relative = database_data_path_relative + escapeForFileName(ast_create_query.table) + '/';
|
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
ast_create_query.table,
|
ast_create_query.table,
|
||||||
@ -202,7 +112,6 @@ String getObjectDefinitionFromCreateQuery(const ASTPtr & query)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseOnDisk::createTable(
|
void DatabaseOnDisk::createTable(
|
||||||
IDatabase & database,
|
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
const StoragePtr & table,
|
const StoragePtr & table,
|
||||||
@ -222,14 +131,14 @@ void DatabaseOnDisk::createTable(
|
|||||||
/// A race condition would be possible if a table with the same name is simultaneously created using CREATE and using ATTACH.
|
/// A race condition would be possible if a table with the same name is simultaneously created using CREATE and using ATTACH.
|
||||||
/// But there is protection from it - see using DDLGuard in InterpreterCreateQuery.
|
/// But there is protection from it - see using DDLGuard in InterpreterCreateQuery.
|
||||||
|
|
||||||
if (database.isDictionaryExist(context, table_name))
|
if (isDictionaryExist(context, table_name))
|
||||||
throw Exception("Dictionary " + backQuote(database.getDatabaseName()) + "." + backQuote(table_name) + " already exists.",
|
throw Exception("Dictionary " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " already exists.",
|
||||||
ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
||||||
|
|
||||||
if (database.isTableExist(context, table_name))
|
if (isTableExist(context, table_name))
|
||||||
throw Exception("Table " + backQuote(database.getDatabaseName()) + "." + backQuote(table_name) + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
||||||
|
|
||||||
String table_metadata_path = database.getObjectMetadataPath(table_name);
|
String table_metadata_path = getObjectMetadataPath(table_name);
|
||||||
String table_metadata_tmp_path = table_metadata_path + ".tmp";
|
String table_metadata_tmp_path = table_metadata_path + ".tmp";
|
||||||
String statement;
|
String statement;
|
||||||
|
|
||||||
@ -248,7 +157,7 @@ void DatabaseOnDisk::createTable(
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
/// Add a table to the map of known tables.
|
/// Add a table to the map of known tables.
|
||||||
database.attachTable(table_name, table);
|
attachTable(table_name, table);
|
||||||
|
|
||||||
/// If it was ATTACH query and file with table metadata already exist
|
/// If it was ATTACH query and file with table metadata already exist
|
||||||
/// (so, ATTACH is done after DETACH), then rename atomically replaces old file with new one.
|
/// (so, ATTACH is done after DETACH), then rename atomically replaces old file with new one.
|
||||||
@ -261,107 +170,11 @@ void DatabaseOnDisk::createTable(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseOnDisk::removeTable(const Context & /* context */, const String & table_name)
|
||||||
void DatabaseOnDisk::createDictionary(
|
|
||||||
IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
const ASTPtr & query)
|
|
||||||
{
|
{
|
||||||
const auto & settings = context.getSettingsRef();
|
StoragePtr res = detachTable(table_name);
|
||||||
|
|
||||||
/** The code is based on the assumption that all threads share the same order of operations:
|
String table_metadata_path = getObjectMetadataPath(table_name);
|
||||||
* - create the .sql.tmp file;
|
|
||||||
* - add the dictionary to ExternalDictionariesLoader;
|
|
||||||
* - load the dictionary in case dictionaries_lazy_load == false;
|
|
||||||
* - attach the dictionary;
|
|
||||||
* - rename .sql.tmp to .sql.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// A race condition would be possible if a dictionary with the same name is simultaneously created using CREATE and using ATTACH.
|
|
||||||
/// But there is protection from it - see using DDLGuard in InterpreterCreateQuery.
|
|
||||||
if (database.isDictionaryExist(context, dictionary_name))
|
|
||||||
throw Exception("Dictionary " + backQuote(database.getDatabaseName()) + "." + backQuote(dictionary_name) + " already exists.", ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
|
||||||
|
|
||||||
/// A dictionary with the same full name could be defined in *.xml config files.
|
|
||||||
String full_name = database.getDatabaseName() + "." + dictionary_name;
|
|
||||||
auto & external_loader = const_cast<ExternalDictionariesLoader &>(context.getExternalDictionariesLoader());
|
|
||||||
if (external_loader.getCurrentStatus(full_name) != ExternalLoader::Status::NOT_EXIST)
|
|
||||||
throw Exception(
|
|
||||||
"Dictionary " + backQuote(database.getDatabaseName()) + "." + backQuote(dictionary_name) + " already exists.",
|
|
||||||
ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
|
||||||
|
|
||||||
if (database.isTableExist(context, dictionary_name))
|
|
||||||
throw Exception("Table " + backQuote(database.getDatabaseName()) + "." + backQuote(dictionary_name) + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
|
||||||
|
|
||||||
String dictionary_metadata_path = database.getObjectMetadataPath(dictionary_name);
|
|
||||||
String dictionary_metadata_tmp_path = dictionary_metadata_path + ".tmp";
|
|
||||||
String statement = getObjectDefinitionFromCreateQuery(query);
|
|
||||||
|
|
||||||
{
|
|
||||||
/// Exclusive flags guarantees, that table is not created right now in another thread. Otherwise, exception will be thrown.
|
|
||||||
WriteBufferFromFile out(dictionary_metadata_tmp_path, statement.size(), O_WRONLY | O_CREAT | O_EXCL);
|
|
||||||
writeString(statement, out);
|
|
||||||
out.next();
|
|
||||||
if (settings.fsync_metadata)
|
|
||||||
out.sync();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool succeeded = false;
|
|
||||||
SCOPE_EXIT({
|
|
||||||
if (!succeeded)
|
|
||||||
Poco::File(dictionary_metadata_tmp_path).remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Add a temporary repository containing the dictionary.
|
|
||||||
/// We need this temp repository to try loading the dictionary before actually attaching it to the database.
|
|
||||||
static std::atomic<size_t> counter = 0;
|
|
||||||
String temp_repository_name = String(IExternalLoaderConfigRepository::INTERNAL_REPOSITORY_NAME_PREFIX) + " creating " + full_name + " "
|
|
||||||
+ std::to_string(++counter);
|
|
||||||
external_loader.addConfigRepository(
|
|
||||||
temp_repository_name,
|
|
||||||
std::make_unique<ExternalLoaderPresetConfigRepository>(
|
|
||||||
std::vector{std::pair{dictionary_metadata_tmp_path,
|
|
||||||
getDictionaryConfigurationFromAST(query->as<const ASTCreateQuery &>(), database.getDatabaseName())}}));
|
|
||||||
SCOPE_EXIT({ external_loader.removeConfigRepository(temp_repository_name); });
|
|
||||||
|
|
||||||
bool lazy_load = context.getConfigRef().getBool("dictionaries_lazy_load", true);
|
|
||||||
if (!lazy_load)
|
|
||||||
{
|
|
||||||
/// load() is called here to force loading the dictionary, wait until the loading is finished,
|
|
||||||
/// and throw an exception if the loading is failed.
|
|
||||||
external_loader.load(full_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
database.attachDictionary(dictionary_name, context);
|
|
||||||
SCOPE_EXIT({
|
|
||||||
if (!succeeded)
|
|
||||||
database.detachDictionary(dictionary_name, context);
|
|
||||||
});
|
|
||||||
|
|
||||||
/// If it was ATTACH query and file with dictionary metadata already exist
|
|
||||||
/// (so, ATTACH is done after DETACH), then rename atomically replaces old file with new one.
|
|
||||||
Poco::File(dictionary_metadata_tmp_path).renameTo(dictionary_metadata_path);
|
|
||||||
|
|
||||||
/// ExternalDictionariesLoader doesn't know we renamed the metadata path.
|
|
||||||
/// So we have to manually call reloadConfig() here.
|
|
||||||
external_loader.reloadConfig(database.getDatabaseName(), full_name);
|
|
||||||
|
|
||||||
/// Everything's ok.
|
|
||||||
succeeded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DatabaseOnDisk::removeTable(
|
|
||||||
IDatabase & database,
|
|
||||||
const Context & /* context */,
|
|
||||||
const String & table_name,
|
|
||||||
Poco::Logger * log)
|
|
||||||
{
|
|
||||||
StoragePtr res = database.detachTable(table_name);
|
|
||||||
|
|
||||||
String table_metadata_path = database.getObjectMetadataPath(table_name);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -378,51 +191,64 @@ void DatabaseOnDisk::removeTable(
|
|||||||
{
|
{
|
||||||
LOG_WARNING(log, getCurrentExceptionMessage(__PRETTY_FUNCTION__));
|
LOG_WARNING(log, getCurrentExceptionMessage(__PRETTY_FUNCTION__));
|
||||||
}
|
}
|
||||||
database.attachTable(table_name, res);
|
attachTable(table_name, res);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseOnDisk::renameTable(
|
||||||
void DatabaseOnDisk::removeDictionary(
|
const Context & context,
|
||||||
IDatabase & database,
|
const String & table_name,
|
||||||
const Context & context,
|
IDatabase & to_database,
|
||||||
const String & dictionary_name,
|
const String & to_table_name,
|
||||||
Poco::Logger * /*log*/)
|
TableStructureWriteLockHolder & lock)
|
||||||
{
|
{
|
||||||
database.detachDictionary(dictionary_name, context);
|
if (typeid(*this) != typeid(to_database))
|
||||||
|
throw Exception("Moving tables between databases of different engines is not supported", ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
|
||||||
String dictionary_metadata_path = database.getObjectMetadataPath(dictionary_name);
|
StoragePtr table = tryGetTable(context, table_name);
|
||||||
if (Poco::File(dictionary_metadata_path).exists())
|
|
||||||
|
if (!table)
|
||||||
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
|
|
||||||
|
ASTPtr ast = parseQueryFromMetadata(getObjectMetadataPath(table_name));
|
||||||
|
if (!ast)
|
||||||
|
throw Exception("There is no metadata file for table " + backQuote(table_name) + ".", ErrorCodes::FILE_DOESNT_EXIST);
|
||||||
|
auto & create = ast->as<ASTCreateQuery &>();
|
||||||
|
create.table = to_table_name;
|
||||||
|
|
||||||
|
/// Notify the table that it is renamed. If the table does not support renaming, exception is thrown.
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
table->rename(to_database.getTableDataPath(create),
|
||||||
{
|
to_database.getDatabaseName(),
|
||||||
Poco::File(dictionary_metadata_path).remove();
|
to_table_name, lock);
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
/// If remove was not possible for some reason
|
|
||||||
database.attachDictionary(dictionary_name, context);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (const Exception &)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const Poco::Exception & e)
|
||||||
|
{
|
||||||
|
/// Better diagnostics.
|
||||||
|
throw Exception{Exception::CreateFromPoco, e};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NOTE Non-atomic.
|
||||||
|
to_database.createTable(context, to_table_name, table, ast);
|
||||||
|
removeTable(context, table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTPtr DatabaseOnDisk::getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const
|
||||||
ASTPtr DatabaseOnDisk::getCreateTableQueryImpl(
|
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
bool throw_on_error)
|
|
||||||
{
|
{
|
||||||
ASTPtr ast;
|
ASTPtr ast;
|
||||||
|
|
||||||
auto table_metadata_path = detail::getObjectMetadataPath(database.getMetadataPath(), table_name);
|
auto table_metadata_path = getObjectMetadataPath(table_name);
|
||||||
ast = detail::getCreateQueryFromMetadata(table_metadata_path, database.getDatabaseName(), throw_on_error);
|
ast = getCreateQueryFromMetadata(table_metadata_path, throw_on_error);
|
||||||
if (!ast && throw_on_error)
|
if (!ast && throw_on_error)
|
||||||
{
|
{
|
||||||
/// Handle system.* tables for which there are no table.sql files.
|
/// Handle system.* tables for which there are no table.sql files.
|
||||||
bool has_table = database.tryGetTable(context, table_name) != nullptr;
|
bool has_table = tryGetTable(context, table_name) != nullptr;
|
||||||
|
|
||||||
auto msg = has_table
|
auto msg = has_table
|
||||||
? "There is no CREATE TABLE query for table "
|
? "There is no CREATE TABLE query for table "
|
||||||
@ -434,61 +260,18 @@ ASTPtr DatabaseOnDisk::getCreateTableQueryImpl(
|
|||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTPtr DatabaseOnDisk::getCreateDatabaseQuery() const
|
||||||
ASTPtr DatabaseOnDisk::getCreateDictionaryQueryImpl(
|
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
bool throw_on_error)
|
|
||||||
{
|
{
|
||||||
ASTPtr ast;
|
ASTPtr ast;
|
||||||
|
|
||||||
auto dictionary_metadata_path = detail::getObjectMetadataPath(database.getMetadataPath(), dictionary_name);
|
auto metadata_dir_path = getMetadataPath();
|
||||||
ast = detail::getCreateQueryFromMetadata(dictionary_metadata_path, database.getDatabaseName(), throw_on_error);
|
auto database_metadata_path = metadata_dir_path.substr(0, metadata_dir_path.size() - 1) + ".sql";
|
||||||
if (!ast && throw_on_error)
|
ast = getCreateQueryFromMetadata(database_metadata_path, true);
|
||||||
{
|
|
||||||
/// Handle system.* tables for which there are no table.sql files.
|
|
||||||
bool has_dictionary = database.isDictionaryExist(context, dictionary_name);
|
|
||||||
|
|
||||||
auto msg = has_dictionary ? "There is no CREATE DICTIONARY query for table " : "There is no metadata file for dictionary ";
|
|
||||||
|
|
||||||
throw Exception(msg + backQuote(dictionary_name), ErrorCodes::CANNOT_GET_CREATE_DICTIONARY_QUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ast;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOnDisk::getCreateTableQuery(const IDatabase & database, const Context & context, const String & table_name)
|
|
||||||
{
|
|
||||||
return getCreateTableQueryImpl(database, context, table_name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOnDisk::tryGetCreateTableQuery(const IDatabase & database, const Context & context, const String & table_name)
|
|
||||||
{
|
|
||||||
return getCreateTableQueryImpl(database, context, table_name, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASTPtr DatabaseOnDisk::getCreateDictionaryQuery(const IDatabase & database, const Context & context, const String & dictionary_name)
|
|
||||||
{
|
|
||||||
return getCreateDictionaryQueryImpl(database, context, dictionary_name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOnDisk::tryGetCreateDictionaryQuery(const IDatabase & database, const Context & context, const String & dictionary_name)
|
|
||||||
{
|
|
||||||
return getCreateDictionaryQueryImpl(database, context, dictionary_name, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOnDisk::getCreateDatabaseQuery(const IDatabase & database, const Context & /*context*/)
|
|
||||||
{
|
|
||||||
ASTPtr ast;
|
|
||||||
|
|
||||||
auto database_metadata_path = detail::getDatabaseMetadataPath(database.getMetadataPath());
|
|
||||||
ast = detail::getCreateQueryFromMetadata(database_metadata_path, database.getDatabaseName(), true);
|
|
||||||
if (!ast)
|
if (!ast)
|
||||||
{
|
{
|
||||||
/// Handle databases (such as default) for which there are no database.sql files.
|
/// Handle databases (such as default) for which there are no database.sql files.
|
||||||
String query = "CREATE DATABASE " + backQuoteIfNeed(database.getDatabaseName()) + " ENGINE = Lazy";
|
/// If database.sql doesn't exist, then engine is Ordinary
|
||||||
|
String query = "CREATE DATABASE " + backQuoteIfNeed(getDatabaseName()) + " ENGINE = Ordinary";
|
||||||
ParserCreateQuery parser;
|
ParserCreateQuery parser;
|
||||||
ast = parseQuery(parser, query.data(), query.data() + query.size(), "", 0);
|
ast = parseQuery(parser, query.data(), query.data() + query.size(), "", 0);
|
||||||
}
|
}
|
||||||
@ -496,22 +279,20 @@ ASTPtr DatabaseOnDisk::getCreateDatabaseQuery(const IDatabase & database, const
|
|||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseOnDisk::drop(const IDatabase & database, const Context & context)
|
void DatabaseOnDisk::drop(const Context & context)
|
||||||
{
|
{
|
||||||
Poco::File(context.getPath() + database.getDataPath()).remove(false);
|
Poco::File(context.getPath() + getDataPath()).remove(false);
|
||||||
Poco::File(database.getMetadataPath()).remove(false);
|
Poco::File(getMetadataPath()).remove(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
String DatabaseOnDisk::getObjectMetadataPath(const IDatabase & database, const String & table_name)
|
String DatabaseOnDisk::getObjectMetadataPath(const String & table_name) const
|
||||||
{
|
{
|
||||||
return detail::getObjectMetadataPath(database.getMetadataPath(), table_name);
|
return getMetadataPath() + escapeForFileName(table_name) + ".sql";
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t DatabaseOnDisk::getObjectMetadataModificationTime(
|
time_t DatabaseOnDisk::getObjectMetadataModificationTime(const String & table_name) const
|
||||||
const IDatabase & database,
|
|
||||||
const String & table_name)
|
|
||||||
{
|
{
|
||||||
String table_metadata_path = getObjectMetadataPath(database, table_name);
|
String table_metadata_path = getObjectMetadataPath(table_name);
|
||||||
Poco::File meta_file(table_metadata_path);
|
Poco::File meta_file(table_metadata_path);
|
||||||
|
|
||||||
if (meta_file.exists())
|
if (meta_file.exists())
|
||||||
@ -520,10 +301,10 @@ time_t DatabaseOnDisk::getObjectMetadataModificationTime(
|
|||||||
return static_cast<time_t>(0);
|
return static_cast<time_t>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseOnDisk::iterateMetadataFiles(const IDatabase & database, Poco::Logger * log, const Context & context, const IteratingFunction & iterating_function)
|
void DatabaseOnDisk::iterateMetadataFiles(const Context & context, const IteratingFunction & iterating_function) const
|
||||||
{
|
{
|
||||||
Poco::DirectoryIterator dir_end;
|
Poco::DirectoryIterator dir_end;
|
||||||
for (Poco::DirectoryIterator dir_it(database.getMetadataPath()); dir_it != dir_end; ++dir_it)
|
for (Poco::DirectoryIterator dir_it(getMetadataPath()); dir_it != dir_end; ++dir_it)
|
||||||
{
|
{
|
||||||
/// For '.svn', '.gitignore' directory and similar.
|
/// For '.svn', '.gitignore' directory and similar.
|
||||||
if (dir_it.name().at(0) == '.')
|
if (dir_it.name().at(0) == '.')
|
||||||
@ -538,10 +319,10 @@ void DatabaseOnDisk::iterateMetadataFiles(const IDatabase & database, Poco::Logg
|
|||||||
if (endsWith(dir_it.name(), tmp_drop_ext))
|
if (endsWith(dir_it.name(), tmp_drop_ext))
|
||||||
{
|
{
|
||||||
const std::string object_name = dir_it.name().substr(0, dir_it.name().size() - strlen(tmp_drop_ext));
|
const std::string object_name = dir_it.name().substr(0, dir_it.name().size() - strlen(tmp_drop_ext));
|
||||||
if (Poco::File(context.getPath() + database.getDataPath() + '/' + object_name).exists())
|
if (Poco::File(context.getPath() + getDataPath() + '/' + object_name).exists())
|
||||||
{
|
{
|
||||||
/// TODO maybe complete table drop and remove all table data (including data on other volumes and metadata in ZK)
|
/// TODO maybe complete table drop and remove all table data (including data on other volumes and metadata in ZK)
|
||||||
Poco::File(dir_it->path()).renameTo(database.getMetadataPath() + object_name + ".sql");
|
Poco::File(dir_it->path()).renameTo(getMetadataPath() + object_name + ".sql");
|
||||||
LOG_WARNING(log, "Object " << backQuote(object_name) << " was not dropped previously and will be restored");
|
LOG_WARNING(log, "Object " << backQuote(object_name) << " was not dropped previously and will be restored");
|
||||||
iterating_function(object_name + ".sql");
|
iterating_function(object_name + ".sql");
|
||||||
}
|
}
|
||||||
@ -567,9 +348,64 @@ void DatabaseOnDisk::iterateMetadataFiles(const IDatabase & database, Poco::Logg
|
|||||||
iterating_function(dir_it.name());
|
iterating_function(dir_it.name());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw Exception("Incorrect file extension: " + dir_it.name() + " in metadata directory " + database.getMetadataPath(),
|
throw Exception("Incorrect file extension: " + dir_it.name() + " in metadata directory " + getMetadataPath(),
|
||||||
ErrorCodes::INCORRECT_FILE_NAME);
|
ErrorCodes::INCORRECT_FILE_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTPtr DatabaseOnDisk::parseQueryFromMetadata(const String & metadata_file_path, bool throw_on_error /*= true*/, bool remove_empty /*= false*/) const
|
||||||
|
{
|
||||||
|
String query;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ReadBufferFromFile in(metadata_file_path, METADATA_FILE_BUFFER_SIZE);
|
||||||
|
readStringUntilEOF(query, in);
|
||||||
|
}
|
||||||
|
catch (const Exception & e)
|
||||||
|
{
|
||||||
|
if (!throw_on_error && e.code() == ErrorCodes::FILE_DOESNT_EXIST)
|
||||||
|
return nullptr;
|
||||||
|
else
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Empty files with metadata are generated after a rough restart of the server.
|
||||||
|
* Remove these files to slightly reduce the work of the admins on startup.
|
||||||
|
*/
|
||||||
|
if (remove_empty && query.empty())
|
||||||
|
{
|
||||||
|
LOG_ERROR(log, "File " << metadata_file_path << " is empty. Removing.");
|
||||||
|
Poco::File(metadata_file_path).remove();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParserCreateQuery parser;
|
||||||
|
const char * pos = query.data();
|
||||||
|
std::string error_message;
|
||||||
|
auto ast = tryParseQuery(parser, pos, pos + query.size(), error_message, /* hilite = */ false,
|
||||||
|
"in file " + getMetadataPath(), /* allow_multi_statements = */ false, 0);
|
||||||
|
|
||||||
|
if (!ast && throw_on_error)
|
||||||
|
throw Exception(error_message, ErrorCodes::SYNTAX_ERROR);
|
||||||
|
else if (!ast)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTPtr DatabaseOnDisk::getCreateQueryFromMetadata(const String & database_metadata_path, bool throw_on_error) const
|
||||||
|
{
|
||||||
|
ASTPtr ast = parseQueryFromMetadata(database_metadata_path, throw_on_error);
|
||||||
|
|
||||||
|
if (ast)
|
||||||
|
{
|
||||||
|
auto & ast_create_query = ast->as<ASTCreateQuery &>();
|
||||||
|
ast_create_query.attach = false;
|
||||||
|
ast_create_query.database = database_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,24 +11,14 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
String getObjectMetadataPath(const String & base_path, const String & dictionary_name);
|
|
||||||
String getDatabaseMetadataPath(const String & base_path);
|
|
||||||
ASTPtr getQueryFromMetadata(const String & metadata_path, bool throw_on_error = true);
|
|
||||||
ASTPtr getCreateQueryFromMetadata(const String & metadata_path, const String & database, bool throw_on_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr parseCreateQueryFromMetadataFile(const String & filepath, Poco::Logger * log);
|
|
||||||
|
|
||||||
std::pair<String, StoragePtr> createTableFromAST(
|
std::pair<String, StoragePtr> createTableFromAST(
|
||||||
ASTCreateQuery ast_create_query,
|
ASTCreateQuery ast_create_query,
|
||||||
const String & database_name,
|
const String & database_name,
|
||||||
const String & database_data_path_relative,
|
const String & table_data_path_relative,
|
||||||
Context & context,
|
Context & context,
|
||||||
bool has_force_restore_data_flag);
|
bool has_force_restore_data_flag);
|
||||||
|
|
||||||
/** Get the row with the table definition based on the CREATE query.
|
/** Get the string with the table definition based on the CREATE query.
|
||||||
* It is an ATTACH query that you can execute to create a table from the correspondent database.
|
* It is an ATTACH query that you can execute to create a table from the correspondent database.
|
||||||
* See the implementation.
|
* See the implementation.
|
||||||
*/
|
*/
|
||||||
@ -37,147 +27,59 @@ String getObjectDefinitionFromCreateQuery(const ASTPtr & query);
|
|||||||
|
|
||||||
/* Class to provide basic operations with tables when metadata is stored on disk in .sql files.
|
/* Class to provide basic operations with tables when metadata is stored on disk in .sql files.
|
||||||
*/
|
*/
|
||||||
class DatabaseOnDisk
|
class DatabaseOnDisk : public DatabaseWithOwnTablesBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void createTable(
|
DatabaseOnDisk(const String & name, const String & metadata_path_, const String & logger)
|
||||||
IDatabase & database,
|
: DatabaseWithOwnTablesBase(name, logger)
|
||||||
|
, metadata_path(metadata_path_)
|
||||||
|
, data_path("data/" + escapeForFileName(database_name) + "/") {}
|
||||||
|
|
||||||
|
void createTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
const StoragePtr & table,
|
const StoragePtr & table,
|
||||||
const ASTPtr & query);
|
const ASTPtr & query) override;
|
||||||
|
|
||||||
static void createDictionary(
|
void removeTable(
|
||||||
IDatabase & database,
|
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & dictionary_name,
|
const String & table_name) override;
|
||||||
const ASTPtr & query);
|
|
||||||
|
|
||||||
static void removeTable(
|
void renameTable(
|
||||||
IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
Poco::Logger * log);
|
|
||||||
|
|
||||||
static void removeDictionary(
|
|
||||||
IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
Poco::Logger * log);
|
|
||||||
|
|
||||||
template <typename Database>
|
|
||||||
static void renameTable(
|
|
||||||
IDatabase & database,
|
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
IDatabase & to_database,
|
IDatabase & to_database,
|
||||||
const String & to_table_name,
|
const String & to_table_name,
|
||||||
TableStructureWriteLockHolder & lock);
|
TableStructureWriteLockHolder & lock) override;
|
||||||
|
|
||||||
static ASTPtr getCreateTableQuery(
|
ASTPtr getCreateDatabaseQuery() const override;
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name);
|
|
||||||
|
|
||||||
static ASTPtr tryGetCreateTableQuery(
|
void drop(const Context & context) override;
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name);
|
|
||||||
|
|
||||||
static ASTPtr getCreateDictionaryQuery(
|
String getObjectMetadataPath(const String & object_name) const override;
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name);
|
|
||||||
|
|
||||||
static ASTPtr tryGetCreateDictionaryQuery(
|
time_t getObjectMetadataModificationTime(const String & object_name) const override;
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name);
|
|
||||||
|
|
||||||
static ASTPtr getCreateDatabaseQuery(
|
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context);
|
|
||||||
|
|
||||||
static void drop(const IDatabase & database, const Context & context);
|
|
||||||
|
|
||||||
static String getObjectMetadataPath(
|
|
||||||
const IDatabase & database,
|
|
||||||
const String & object_name);
|
|
||||||
|
|
||||||
static time_t getObjectMetadataModificationTime(
|
|
||||||
const IDatabase & database,
|
|
||||||
const String & object_name);
|
|
||||||
|
|
||||||
|
String getDataPath() const override { return data_path; }
|
||||||
|
String getTableDataPath(const String & table_name) const override { return data_path + escapeForFileName(table_name) + "/"; }
|
||||||
|
String getTableDataPath(const ASTCreateQuery & query) const override { return getTableDataPath(query.table); }
|
||||||
|
String getMetadataPath() const override { return metadata_path; }
|
||||||
|
|
||||||
|
protected:
|
||||||
using IteratingFunction = std::function<void(const String &)>;
|
using IteratingFunction = std::function<void(const String &)>;
|
||||||
static void iterateMetadataFiles(const IDatabase & database, Poco::Logger * log, const Context & context, const IteratingFunction & iterating_function);
|
void iterateMetadataFiles(const Context & context, const IteratingFunction & iterating_function) const;
|
||||||
|
|
||||||
private:
|
ASTPtr getCreateTableQueryImpl(
|
||||||
static ASTPtr getCreateTableQueryImpl(
|
|
||||||
const IDatabase & database,
|
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
bool throw_on_error);
|
bool throw_on_error) const override;
|
||||||
|
|
||||||
static ASTPtr getCreateDictionaryQueryImpl(
|
ASTPtr parseQueryFromMetadata(const String & metadata_file_path, bool throw_on_error = true, bool remove_empty = false) const;
|
||||||
const IDatabase & database,
|
ASTPtr getCreateQueryFromMetadata(const String & metadata_path, bool throw_on_error) const;
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
bool throw_on_error);
|
const String metadata_path;
|
||||||
|
const String data_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace ErrorCodes
|
|
||||||
{
|
|
||||||
extern const int NOT_IMPLEMENTED;
|
|
||||||
extern const int UNKNOWN_TABLE;
|
|
||||||
extern const int FILE_DOESNT_EXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Database>
|
|
||||||
void DatabaseOnDisk::renameTable(
|
|
||||||
IDatabase & database,
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
IDatabase & to_database,
|
|
||||||
const String & to_table_name,
|
|
||||||
TableStructureWriteLockHolder & lock)
|
|
||||||
{
|
|
||||||
Database * to_database_concrete = typeid_cast<Database *>(&to_database);
|
|
||||||
|
|
||||||
if (!to_database_concrete)
|
|
||||||
throw Exception("Moving tables between databases of different engines is not supported", ErrorCodes::NOT_IMPLEMENTED);
|
|
||||||
|
|
||||||
StoragePtr table = database.tryGetTable(context, table_name);
|
|
||||||
|
|
||||||
if (!table)
|
|
||||||
throw Exception("Table " + backQuote(database.getDatabaseName()) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
||||||
|
|
||||||
/// Notify the table that it is renamed. If the table does not support renaming, exception is thrown.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
table->rename("/data/" + escapeForFileName(to_database_concrete->getDatabaseName()) + "/" + escapeForFileName(to_table_name) + '/',
|
|
||||||
to_database_concrete->getDatabaseName(),
|
|
||||||
to_table_name, lock);
|
|
||||||
}
|
|
||||||
catch (const Exception &)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (const Poco::Exception & e)
|
|
||||||
{
|
|
||||||
/// Better diagnostics.
|
|
||||||
throw Exception{Exception::CreateFromPoco, e};
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr ast = detail::getQueryFromMetadata(detail::getObjectMetadataPath(database.getMetadataPath(), table_name));
|
|
||||||
if (!ast)
|
|
||||||
throw Exception("There is no metadata file for table " + backQuote(table_name) + ".", ErrorCodes::FILE_DOESNT_EXIST);
|
|
||||||
ast->as<ASTCreateQuery &>().table = to_table_name;
|
|
||||||
|
|
||||||
/// NOTE Non-atomic.
|
|
||||||
to_database_concrete->createTable(context, to_table_name, table, ast);
|
|
||||||
database.removeTable(context, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#include <Core/Settings.h>
|
#include <Core/Settings.h>
|
||||||
#include <Databases/DatabaseMemory.h>
|
|
||||||
#include <Databases/DatabaseOnDisk.h>
|
#include <Databases/DatabaseOnDisk.h>
|
||||||
#include <Databases/DatabaseOrdinary.h>
|
#include <Databases/DatabaseOrdinary.h>
|
||||||
#include <Databases/DatabasesCommon.h>
|
#include <Databases/DatabasesCommon.h>
|
||||||
@ -15,13 +14,10 @@
|
|||||||
#include <Interpreters/ExternalDictionariesLoader.h>
|
#include <Interpreters/ExternalDictionariesLoader.h>
|
||||||
#include <Parsers/ASTCreateQuery.h>
|
#include <Parsers/ASTCreateQuery.h>
|
||||||
#include <Parsers/ParserCreateQuery.h>
|
#include <Parsers/ParserCreateQuery.h>
|
||||||
#include <Parsers/ParserDictionary.h>
|
|
||||||
#include <Storages/StorageFactory.h>
|
#include <Storages/StorageFactory.h>
|
||||||
#include <Dictionaries/DictionaryFactory.h>
|
|
||||||
#include <Parsers/parseQuery.h>
|
#include <Parsers/parseQuery.h>
|
||||||
#include <Parsers/formatAST.h>
|
#include <Parsers/formatAST.h>
|
||||||
#include <Parsers/ASTSetQuery.h>
|
#include <Parsers/ASTSetQuery.h>
|
||||||
#include <Storages/IStorage.h>
|
|
||||||
#include <TableFunctions/TableFunctionFactory.h>
|
#include <TableFunctions/TableFunctionFactory.h>
|
||||||
|
|
||||||
#include <Parsers/queryToString.h>
|
#include <Parsers/queryToString.h>
|
||||||
@ -29,7 +25,6 @@
|
|||||||
#include <Poco/DirectoryIterator.h>
|
#include <Poco/DirectoryIterator.h>
|
||||||
#include <Poco/Event.h>
|
#include <Poco/Event.h>
|
||||||
#include <Common/Stopwatch.h>
|
#include <Common/Stopwatch.h>
|
||||||
#include <Common/StringUtils/StringUtils.h>
|
|
||||||
#include <Common/quoteString.h>
|
#include <Common/quoteString.h>
|
||||||
#include <Common/ThreadPool.h>
|
#include <Common/ThreadPool.h>
|
||||||
#include <Common/escapeForFileName.h>
|
#include <Common/escapeForFileName.h>
|
||||||
@ -47,7 +42,6 @@ namespace ErrorCodes
|
|||||||
extern const int CANNOT_CREATE_DICTIONARY_FROM_METADATA;
|
extern const int CANNOT_CREATE_DICTIONARY_FROM_METADATA;
|
||||||
extern const int EMPTY_LIST_OF_COLUMNS_PASSED;
|
extern const int EMPTY_LIST_OF_COLUMNS_PASSED;
|
||||||
extern const int CANNOT_PARSE_TEXT;
|
extern const int CANNOT_PARSE_TEXT;
|
||||||
extern const int EMPTY_LIST_OF_ATTRIBUTES_PASSED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +65,7 @@ namespace
|
|||||||
String table_name;
|
String table_name;
|
||||||
StoragePtr table;
|
StoragePtr table;
|
||||||
std::tie(table_name, table)
|
std::tie(table_name, table)
|
||||||
= createTableFromAST(query, database_name, database.getDataPath(), context, has_force_restore_data_flag);
|
= createTableFromAST(query, database_name, database.getTableDataPath(query), context, has_force_restore_data_flag);
|
||||||
database.attachTable(table_name, table);
|
database.attachTable(table_name, table);
|
||||||
}
|
}
|
||||||
catch (const Exception & e)
|
catch (const Exception & e)
|
||||||
@ -117,11 +111,8 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DatabaseOrdinary::DatabaseOrdinary(String name_, const String & metadata_path_, const Context & context_)
|
DatabaseOrdinary::DatabaseOrdinary(const String & name_, const String & metadata_path_, const Context & context_)
|
||||||
: DatabaseWithOwnTablesBase(std::move(name_))
|
: DatabaseWithDictionaries(name_, metadata_path_, "DatabaseOrdinary (" + name_ + ")")
|
||||||
, metadata_path(metadata_path_)
|
|
||||||
, data_path("data/" + escapeForFileName(name) + "/")
|
|
||||||
, log(&Logger::get("DatabaseOrdinary (" + name + ")"))
|
|
||||||
{
|
{
|
||||||
Poco::File(context_.getPath() + getDataPath()).createDirectories();
|
Poco::File(context_.getPath() + getDataPath()).createDirectories();
|
||||||
}
|
}
|
||||||
@ -140,12 +131,12 @@ void DatabaseOrdinary::loadStoredObjects(
|
|||||||
FileNames file_names;
|
FileNames file_names;
|
||||||
|
|
||||||
size_t total_dictionaries = 0;
|
size_t total_dictionaries = 0;
|
||||||
DatabaseOnDisk::iterateMetadataFiles(*this, log, context, [&file_names, &total_dictionaries, this](const String & file_name)
|
iterateMetadataFiles(context, [&file_names, &total_dictionaries, this](const String & file_name)
|
||||||
{
|
{
|
||||||
String full_path = metadata_path + "/" + file_name;
|
String full_path = getMetadataPath() + file_name;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto ast = parseCreateQueryFromMetadataFile(full_path, log);
|
auto ast = parseQueryFromMetadata(full_path, /*throw_on_error*/ true, /*remove_empty*/false);
|
||||||
if (ast)
|
if (ast)
|
||||||
{
|
{
|
||||||
auto * create_query = ast->as<ASTCreateQuery>();
|
auto * create_query = ast->as<ASTCreateQuery>();
|
||||||
@ -240,91 +231,14 @@ void DatabaseOrdinary::startupTables(ThreadPool & thread_pool)
|
|||||||
thread_pool.wait();
|
thread_pool.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseOrdinary::createTable(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
const StoragePtr & table,
|
|
||||||
const ASTPtr & query)
|
|
||||||
{
|
|
||||||
DatabaseOnDisk::createTable(*this, context, table_name, table, query);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseOrdinary::createDictionary(
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
const ASTPtr & query)
|
|
||||||
{
|
|
||||||
DatabaseOnDisk::createDictionary(*this, context, dictionary_name, query);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseOrdinary::removeTable(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name)
|
|
||||||
{
|
|
||||||
DatabaseOnDisk::removeTable(*this, context, table_name, log);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseOrdinary::removeDictionary(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name)
|
|
||||||
{
|
|
||||||
DatabaseOnDisk::removeDictionary(*this, context, table_name, log);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseOrdinary::renameTable(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
IDatabase & to_database,
|
|
||||||
const String & to_table_name,
|
|
||||||
TableStructureWriteLockHolder & lock)
|
|
||||||
{
|
|
||||||
DatabaseOnDisk::renameTable<DatabaseOrdinary>(*this, context, table_name, to_database, to_table_name, lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
time_t DatabaseOrdinary::getObjectMetadataModificationTime(
|
|
||||||
const Context & /* context */,
|
|
||||||
const String & table_name)
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getObjectMetadataModificationTime(*this, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOrdinary::getCreateTableQuery(const Context & context, const String & table_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getCreateTableQuery(*this, context, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOrdinary::tryGetCreateTableQuery(const Context & context, const String & table_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::tryGetCreateTableQuery(*this, context, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ASTPtr DatabaseOrdinary::getCreateDictionaryQuery(const Context & context, const String & dictionary_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getCreateDictionaryQuery(*this, context, dictionary_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOrdinary::tryGetCreateDictionaryQuery(const Context & context, const String & dictionary_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::tryGetCreateTableQuery(*this, context, dictionary_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTPtr DatabaseOrdinary::getCreateDatabaseQuery(const Context & context) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getCreateDatabaseQuery(*this, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseOrdinary::alterTable(
|
void DatabaseOrdinary::alterTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name,
|
const String & table_name,
|
||||||
const StorageInMemoryMetadata & metadata)
|
const StorageInMemoryMetadata & metadata)
|
||||||
{
|
{
|
||||||
/// Read the definition of the table and replace the necessary parts with new ones.
|
/// Read the definition of the table and replace the necessary parts with new ones.
|
||||||
|
String table_metadata_path = getObjectMetadataPath(table_name);
|
||||||
String table_name_escaped = escapeForFileName(table_name);
|
String table_metadata_tmp_path = table_metadata_path + ".tmp";
|
||||||
String table_metadata_tmp_path = getMetadataPath() + "/" + table_name_escaped + ".sql.tmp";
|
|
||||||
String table_metadata_path = getMetadataPath() + "/" + table_name_escaped + ".sql";
|
|
||||||
String statement;
|
String statement;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -383,31 +297,4 @@ void DatabaseOrdinary::alterTable(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseOrdinary::drop(const Context & context)
|
|
||||||
{
|
|
||||||
DatabaseOnDisk::drop(*this, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
String DatabaseOrdinary::getDataPath() const
|
|
||||||
{
|
|
||||||
return data_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
String DatabaseOrdinary::getMetadataPath() const
|
|
||||||
{
|
|
||||||
return metadata_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
String DatabaseOrdinary::getDatabaseName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
String DatabaseOrdinary::getObjectMetadataPath(const String & table_name) const
|
|
||||||
{
|
|
||||||
return DatabaseOnDisk::getObjectMetadataPath(*this, table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Databases/DatabasesCommon.h>
|
#include <Databases/DatabaseWithDictionaries.h>
|
||||||
#include <Common/ThreadPool.h>
|
#include <Common/ThreadPool.h>
|
||||||
|
|
||||||
|
|
||||||
@ -11,10 +11,10 @@ namespace DB
|
|||||||
* It stores tables list in filesystem using list of .sql files,
|
* It stores tables list in filesystem using list of .sql files,
|
||||||
* that contain declaration of table represented by SQL ATTACH TABLE query.
|
* that contain declaration of table represented by SQL ATTACH TABLE query.
|
||||||
*/
|
*/
|
||||||
class DatabaseOrdinary : public DatabaseWithOwnTablesBase
|
class DatabaseOrdinary : public DatabaseWithDictionaries //DatabaseWithOwnTablesBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DatabaseOrdinary(String name_, const String & metadata_path_, const Context & context);
|
DatabaseOrdinary(const String & name_, const String & metadata_path_, const Context & context);
|
||||||
|
|
||||||
String getEngineName() const override { return "Ordinary"; }
|
String getEngineName() const override { return "Ordinary"; }
|
||||||
|
|
||||||
@ -22,70 +22,12 @@ public:
|
|||||||
Context & context,
|
Context & context,
|
||||||
bool has_force_restore_data_flag) override;
|
bool has_force_restore_data_flag) override;
|
||||||
|
|
||||||
void createTable(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
const StoragePtr & table,
|
|
||||||
const ASTPtr & query) override;
|
|
||||||
|
|
||||||
void createDictionary(
|
|
||||||
const Context & context,
|
|
||||||
const String & dictionary_name,
|
|
||||||
const ASTPtr & query) override;
|
|
||||||
|
|
||||||
void removeTable(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) override;
|
|
||||||
|
|
||||||
void removeDictionary(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) override;
|
|
||||||
|
|
||||||
void renameTable(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name,
|
|
||||||
IDatabase & to_database,
|
|
||||||
const String & to_table_name,
|
|
||||||
TableStructureWriteLockHolder &) override;
|
|
||||||
|
|
||||||
void alterTable(
|
void alterTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & name,
|
const String & name,
|
||||||
const StorageInMemoryMetadata & metadata) override;
|
const StorageInMemoryMetadata & metadata) override;
|
||||||
|
|
||||||
time_t getObjectMetadataModificationTime(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) override;
|
|
||||||
|
|
||||||
ASTPtr getCreateTableQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) const override;
|
|
||||||
|
|
||||||
ASTPtr tryGetCreateTableQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & table_name) const override;
|
|
||||||
|
|
||||||
ASTPtr tryGetCreateDictionaryQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & name) const override;
|
|
||||||
|
|
||||||
ASTPtr getCreateDictionaryQuery(
|
|
||||||
const Context & context,
|
|
||||||
const String & name) const override;
|
|
||||||
|
|
||||||
ASTPtr getCreateDatabaseQuery(const Context & context) const override;
|
|
||||||
|
|
||||||
String getDataPath() const override;
|
|
||||||
String getDatabaseName() const override;
|
|
||||||
String getMetadataPath() const override;
|
|
||||||
String getObjectMetadataPath(const String & table_name) const override;
|
|
||||||
|
|
||||||
void drop(const Context & context) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const String metadata_path;
|
|
||||||
const String data_path;
|
|
||||||
Poco::Logger * log;
|
|
||||||
|
|
||||||
void startupTables(ThreadPool & thread_pool);
|
void startupTables(ThreadPool & thread_pool);
|
||||||
};
|
};
|
||||||
|
256
dbms/src/Databases/DatabaseWithDictionaries.cpp
Normal file
256
dbms/src/Databases/DatabaseWithDictionaries.cpp
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
#include <Databases/DatabaseWithDictionaries.h>
|
||||||
|
#include <Interpreters/ExternalDictionariesLoader.h>
|
||||||
|
#include <Interpreters/ExternalLoaderPresetConfigRepository.h>
|
||||||
|
#include <Dictionaries/getDictionaryConfigurationFromAST.h>
|
||||||
|
#include <Interpreters/Context.h>
|
||||||
|
#include <Storages/StorageDictionary.h>
|
||||||
|
#include <IO/WriteBufferFromFile.h>
|
||||||
|
#include <Poco/File.h>
|
||||||
|
#include <ext/scope_guard.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int EMPTY_LIST_OF_COLUMNS_PASSED;
|
||||||
|
extern const int TABLE_ALREADY_EXISTS;
|
||||||
|
extern const int UNKNOWN_TABLE;
|
||||||
|
extern const int LOGICAL_ERROR;
|
||||||
|
extern const int DICTIONARY_ALREADY_EXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DatabaseWithDictionaries::attachDictionary(const String & dictionary_name, const Context & context)
|
||||||
|
{
|
||||||
|
String full_name = getDatabaseName() + "." + dictionary_name;
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
if (!dictionaries.emplace(dictionary_name).second)
|
||||||
|
throw Exception("Dictionary " + full_name + " already exists.", ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExternalLoader::reloadConfig() will find out that the dictionary's config has been added
|
||||||
|
/// and in case `dictionaries_lazy_load == false` it will load the dictionary.
|
||||||
|
const auto & external_loader = context.getExternalDictionariesLoader();
|
||||||
|
external_loader.reloadConfig(getDatabaseName(), full_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWithDictionaries::detachDictionary(const String & dictionary_name, const Context & context)
|
||||||
|
{
|
||||||
|
String full_name = getDatabaseName() + "." + dictionary_name;
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
auto it = dictionaries.find(dictionary_name);
|
||||||
|
if (it == dictionaries.end())
|
||||||
|
throw Exception("Dictionary " + full_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
|
dictionaries.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExternalLoader::reloadConfig() will find out that the dictionary's config has been removed
|
||||||
|
/// and therefore it will unload the dictionary.
|
||||||
|
const auto & external_loader = context.getExternalDictionariesLoader();
|
||||||
|
external_loader.reloadConfig(getDatabaseName(), full_name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWithDictionaries::createDictionary(const Context & context, const String & dictionary_name, const ASTPtr & query)
|
||||||
|
{
|
||||||
|
const auto & settings = context.getSettingsRef();
|
||||||
|
|
||||||
|
/** The code is based on the assumption that all threads share the same order of operations:
|
||||||
|
* - create the .sql.tmp file;
|
||||||
|
* - add the dictionary to ExternalDictionariesLoader;
|
||||||
|
* - load the dictionary in case dictionaries_lazy_load == false;
|
||||||
|
* - attach the dictionary;
|
||||||
|
* - rename .sql.tmp to .sql.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// A race condition would be possible if a dictionary with the same name is simultaneously created using CREATE and using ATTACH.
|
||||||
|
/// But there is protection from it - see using DDLGuard in InterpreterCreateQuery.
|
||||||
|
if (isDictionaryExist(context, dictionary_name))
|
||||||
|
throw Exception("Dictionary " + backQuote(getDatabaseName()) + "." + backQuote(dictionary_name) + " already exists.", ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
||||||
|
|
||||||
|
/// A dictionary with the same full name could be defined in *.xml config files.
|
||||||
|
String full_name = getDatabaseName() + "." + dictionary_name;
|
||||||
|
auto & external_loader = const_cast<ExternalDictionariesLoader &>(context.getExternalDictionariesLoader());
|
||||||
|
if (external_loader.getCurrentStatus(full_name) != ExternalLoader::Status::NOT_EXIST)
|
||||||
|
throw Exception(
|
||||||
|
"Dictionary " + backQuote(getDatabaseName()) + "." + backQuote(dictionary_name) + " already exists.",
|
||||||
|
ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
||||||
|
|
||||||
|
if (isTableExist(context, dictionary_name))
|
||||||
|
throw Exception("Table " + backQuote(getDatabaseName()) + "." + backQuote(dictionary_name) + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
||||||
|
|
||||||
|
|
||||||
|
String dictionary_metadata_path = getObjectMetadataPath(dictionary_name);
|
||||||
|
String dictionary_metadata_tmp_path = dictionary_metadata_path + ".tmp";
|
||||||
|
String statement = getObjectDefinitionFromCreateQuery(query);
|
||||||
|
|
||||||
|
{
|
||||||
|
/// Exclusive flags guarantees, that table is not created right now in another thread. Otherwise, exception will be thrown.
|
||||||
|
WriteBufferFromFile out(dictionary_metadata_tmp_path, statement.size(), O_WRONLY | O_CREAT | O_EXCL);
|
||||||
|
writeString(statement, out);
|
||||||
|
out.next();
|
||||||
|
if (settings.fsync_metadata)
|
||||||
|
out.sync();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool succeeded = false;
|
||||||
|
SCOPE_EXIT({
|
||||||
|
if (!succeeded)
|
||||||
|
Poco::File(dictionary_metadata_tmp_path).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Add a temporary repository containing the dictionary.
|
||||||
|
/// We need this temp repository to try loading the dictionary before actually attaching it to the database.
|
||||||
|
static std::atomic<size_t> counter = 0;
|
||||||
|
String temp_repository_name = String(IExternalLoaderConfigRepository::INTERNAL_REPOSITORY_NAME_PREFIX) + " creating " + full_name + " "
|
||||||
|
+ std::to_string(++counter);
|
||||||
|
external_loader.addConfigRepository(
|
||||||
|
temp_repository_name,
|
||||||
|
std::make_unique<ExternalLoaderPresetConfigRepository>(
|
||||||
|
std::vector{std::pair{dictionary_metadata_tmp_path,
|
||||||
|
getDictionaryConfigurationFromAST(query->as<const ASTCreateQuery &>(), getDatabaseName())}}));
|
||||||
|
SCOPE_EXIT({ external_loader.removeConfigRepository(temp_repository_name); });
|
||||||
|
|
||||||
|
bool lazy_load = context.getConfigRef().getBool("dictionaries_lazy_load", true);
|
||||||
|
if (!lazy_load)
|
||||||
|
{
|
||||||
|
/// load() is called here to force loading the dictionary, wait until the loading is finished,
|
||||||
|
/// and throw an exception if the loading is failed.
|
||||||
|
external_loader.load(full_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
attachDictionary(dictionary_name, context);
|
||||||
|
SCOPE_EXIT({
|
||||||
|
if (!succeeded)
|
||||||
|
detachDictionary(dictionary_name, context);
|
||||||
|
});
|
||||||
|
|
||||||
|
/// If it was ATTACH query and file with dictionary metadata already exist
|
||||||
|
/// (so, ATTACH is done after DETACH), then rename atomically replaces old file with new one.
|
||||||
|
Poco::File(dictionary_metadata_tmp_path).renameTo(dictionary_metadata_path);
|
||||||
|
|
||||||
|
/// ExternalDictionariesLoader doesn't know we renamed the metadata path.
|
||||||
|
/// So we have to manually call reloadConfig() here.
|
||||||
|
external_loader.reloadConfig(getDatabaseName(), full_name);
|
||||||
|
|
||||||
|
/// Everything's ok.
|
||||||
|
succeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseWithDictionaries::removeDictionary(const Context & context, const String & dictionary_name)
|
||||||
|
{
|
||||||
|
detachDictionary(dictionary_name, context);
|
||||||
|
|
||||||
|
String dictionary_metadata_path = getObjectMetadataPath(dictionary_name);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Poco::File(dictionary_metadata_path).remove();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
/// If remove was not possible for some reason
|
||||||
|
attachDictionary(dictionary_name, context);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const String & table_name) const
|
||||||
|
{
|
||||||
|
if (auto table_ptr = DatabaseWithOwnTablesBase::tryGetTable(context, table_name))
|
||||||
|
return table_ptr;
|
||||||
|
|
||||||
|
if (isDictionaryExist(context, table_name))
|
||||||
|
/// We don't need lock database here, because database doesn't store dictionary itself
|
||||||
|
/// just metadata
|
||||||
|
return getDictionaryStorage(context, table_name);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_name)
|
||||||
|
{
|
||||||
|
/// NOTE: it's not atomic
|
||||||
|
auto tables_it = getTablesIterator(context, filter_by_name);
|
||||||
|
auto dictionaries_it = getDictionariesIterator(context, filter_by_name);
|
||||||
|
|
||||||
|
Tables result;
|
||||||
|
while (tables_it && tables_it->isValid())
|
||||||
|
{
|
||||||
|
result.emplace(tables_it->name(), tables_it->table());
|
||||||
|
tables_it->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dictionaries_it && dictionaries_it->isValid())
|
||||||
|
{
|
||||||
|
auto table_name = dictionaries_it->name();
|
||||||
|
auto table_ptr = getDictionaryStorage(context, table_name);
|
||||||
|
if (table_ptr)
|
||||||
|
result.emplace(table_name, table_ptr);
|
||||||
|
dictionaries_it->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<DatabaseTablesSnapshotIterator>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseDictionariesIteratorPtr DatabaseWithDictionaries::getDictionariesIterator(const Context & /*context*/, const FilterByNameFunction & filter_by_dictionary_name)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
if (!filter_by_dictionary_name)
|
||||||
|
return std::make_unique<DatabaseDictionariesSnapshotIterator>(dictionaries);
|
||||||
|
|
||||||
|
Dictionaries filtered_dictionaries;
|
||||||
|
for (const auto & dictionary_name : dictionaries)
|
||||||
|
if (filter_by_dictionary_name(dictionary_name))
|
||||||
|
filtered_dictionaries.emplace(dictionary_name);
|
||||||
|
return std::make_unique<DatabaseDictionariesSnapshotIterator>(std::move(filtered_dictionaries));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DatabaseWithDictionaries::isDictionaryExist(const Context & /*context*/, const String & dictionary_name) const
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
return dictionaries.find(dictionary_name) != dictionaries.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
StoragePtr DatabaseWithDictionaries::getDictionaryStorage(const Context & context, const String & table_name) const
|
||||||
|
{
|
||||||
|
auto dict_name = database_name + "." + table_name;
|
||||||
|
const auto & external_loader = context.getExternalDictionariesLoader();
|
||||||
|
auto dict_ptr = external_loader.tryGetDictionary(dict_name);
|
||||||
|
if (dict_ptr)
|
||||||
|
{
|
||||||
|
const DictionaryStructure & dictionary_structure = dict_ptr->getStructure();
|
||||||
|
auto columns = StorageDictionary::getNamesAndTypes(dictionary_structure);
|
||||||
|
return StorageDictionary::create(database_name, table_name, ColumnsDescription{columns}, context, true, dict_name);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTPtr DatabaseWithDictionaries::getCreateDictionaryQueryImpl(
|
||||||
|
const Context & context,
|
||||||
|
const String & dictionary_name,
|
||||||
|
bool throw_on_error) const
|
||||||
|
{
|
||||||
|
ASTPtr ast;
|
||||||
|
|
||||||
|
auto dictionary_metadata_path = getObjectMetadataPath(dictionary_name);
|
||||||
|
ast = getCreateQueryFromMetadata(dictionary_metadata_path, throw_on_error);
|
||||||
|
if (!ast && throw_on_error)
|
||||||
|
{
|
||||||
|
/// Handle system.* tables for which there are no table.sql files.
|
||||||
|
bool has_dictionary = isDictionaryExist(context, dictionary_name);
|
||||||
|
|
||||||
|
auto msg = has_dictionary ? "There is no CREATE DICTIONARY query for table " : "There is no metadata file for dictionary ";
|
||||||
|
|
||||||
|
throw Exception(msg + backQuote(dictionary_name), ErrorCodes::CANNOT_GET_CREATE_DICTIONARY_QUERY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
dbms/src/Databases/DatabaseWithDictionaries.h
Normal file
39
dbms/src/Databases/DatabaseWithDictionaries.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include <Databases/DatabaseOnDisk.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseWithDictionaries : public DatabaseOnDisk
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void attachDictionary(const String & name, const Context & context) override;
|
||||||
|
|
||||||
|
void detachDictionary(const String & name, const Context & context) override;
|
||||||
|
|
||||||
|
void createDictionary(const Context & context,
|
||||||
|
const String & dictionary_name,
|
||||||
|
const ASTPtr & query) override;
|
||||||
|
|
||||||
|
void removeDictionary(const Context & context, const String & dictionary_name) override;
|
||||||
|
|
||||||
|
StoragePtr tryGetTable(const Context & context, const String & table_name) const override;
|
||||||
|
|
||||||
|
DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name = {}) override;
|
||||||
|
|
||||||
|
DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name = {}) override;
|
||||||
|
|
||||||
|
bool isDictionaryExist(const Context & context, const String & dictionary_name) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DatabaseWithDictionaries(const String & name, const String & metadata_path_, const String & logger)
|
||||||
|
: DatabaseOnDisk(name, metadata_path_, logger) {}
|
||||||
|
|
||||||
|
StoragePtr getDictionaryStorage(const Context & context, const String & table_name) const;
|
||||||
|
|
||||||
|
ASTPtr getCreateDictionaryQueryImpl(const Context & context,
|
||||||
|
const String & dictionary_name,
|
||||||
|
bool throw_on_error) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,4 @@
|
|||||||
#include <Databases/DatabasesCommon.h>
|
#include <Databases/DatabasesCommon.h>
|
||||||
#include <Interpreters/ExternalDictionariesLoader.h>
|
|
||||||
#include <Interpreters/Context.h>
|
|
||||||
#include <Interpreters/InterpreterCreateQuery.h>
|
#include <Interpreters/InterpreterCreateQuery.h>
|
||||||
#include <Parsers/ParserCreateQuery.h>
|
#include <Parsers/ParserCreateQuery.h>
|
||||||
#include <Parsers/formatAST.h>
|
#include <Parsers/formatAST.h>
|
||||||
@ -22,23 +20,9 @@ namespace ErrorCodes
|
|||||||
extern const int DICTIONARY_ALREADY_EXISTS;
|
extern const int DICTIONARY_ALREADY_EXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
DatabaseWithOwnTablesBase::DatabaseWithOwnTablesBase(const String & name_, const String & logger)
|
||||||
|
: IDatabase(name_), log(&Logger::get(logger))
|
||||||
{
|
{
|
||||||
|
|
||||||
StoragePtr getDictionaryStorage(const Context & context, const String & table_name, const String & db_name)
|
|
||||||
{
|
|
||||||
auto dict_name = db_name + "." + table_name;
|
|
||||||
const auto & external_loader = context.getExternalDictionariesLoader();
|
|
||||||
auto dict_ptr = external_loader.tryGetDictionary(dict_name);
|
|
||||||
if (dict_ptr)
|
|
||||||
{
|
|
||||||
const DictionaryStructure & dictionary_structure = dict_ptr->getStructure();
|
|
||||||
auto columns = StorageDictionary::getNamesAndTypes(dictionary_structure);
|
|
||||||
return StorageDictionary::create(db_name, table_name, ColumnsDescription{columns}, context, true, dict_name);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseWithOwnTablesBase::isTableExist(
|
bool DatabaseWithOwnTablesBase::isTableExist(
|
||||||
@ -49,57 +33,17 @@ bool DatabaseWithOwnTablesBase::isTableExist(
|
|||||||
return tables.find(table_name) != tables.end() || dictionaries.find(table_name) != dictionaries.end();
|
return tables.find(table_name) != tables.end() || dictionaries.find(table_name) != dictionaries.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseWithOwnTablesBase::isDictionaryExist(
|
|
||||||
const Context & /*context*/,
|
|
||||||
const String & dictionary_name) const
|
|
||||||
{
|
|
||||||
std::lock_guard lock(mutex);
|
|
||||||
return dictionaries.find(dictionary_name) != dictionaries.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
StoragePtr DatabaseWithOwnTablesBase::tryGetTable(
|
StoragePtr DatabaseWithOwnTablesBase::tryGetTable(
|
||||||
const Context & context,
|
const Context & /*context*/,
|
||||||
const String & table_name) const
|
const String & table_name) const
|
||||||
{
|
{
|
||||||
{
|
std::lock_guard lock(mutex);
|
||||||
std::lock_guard lock(mutex);
|
auto it = tables.find(table_name);
|
||||||
auto it = tables.find(table_name);
|
if (it != tables.end())
|
||||||
if (it != tables.end())
|
return it->second;
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDictionaryExist(context, table_name))
|
|
||||||
/// We don't need lock database here, because database doesn't store dictionary itself
|
|
||||||
/// just metadata
|
|
||||||
return getDictionaryStorage(context, table_name, getDatabaseName());
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseTablesIteratorPtr DatabaseWithOwnTablesBase::getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_name)
|
|
||||||
{
|
|
||||||
auto tables_it = getTablesIterator(context, filter_by_name);
|
|
||||||
auto dictionaries_it = getDictionariesIterator(context, filter_by_name);
|
|
||||||
|
|
||||||
Tables result;
|
|
||||||
while (tables_it && tables_it->isValid())
|
|
||||||
{
|
|
||||||
result.emplace(tables_it->name(), tables_it->table());
|
|
||||||
tables_it->next();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (dictionaries_it && dictionaries_it->isValid())
|
|
||||||
{
|
|
||||||
auto table_name = dictionaries_it->name();
|
|
||||||
auto table_ptr = getDictionaryStorage(context, table_name, getDatabaseName());
|
|
||||||
if (table_ptr)
|
|
||||||
result.emplace(table_name, table_ptr);
|
|
||||||
dictionaries_it->next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_unique<DatabaseTablesSnapshotIterator>(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
DatabaseTablesIteratorPtr DatabaseWithOwnTablesBase::getTablesIterator(const Context & /*context*/, const FilterByNameFunction & filter_by_table_name)
|
DatabaseTablesIteratorPtr DatabaseWithOwnTablesBase::getTablesIterator(const Context & /*context*/, const FilterByNameFunction & filter_by_table_name)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
@ -114,20 +58,6 @@ DatabaseTablesIteratorPtr DatabaseWithOwnTablesBase::getTablesIterator(const Con
|
|||||||
return std::make_unique<DatabaseTablesSnapshotIterator>(std::move(filtered_tables));
|
return std::make_unique<DatabaseTablesSnapshotIterator>(std::move(filtered_tables));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DatabaseDictionariesIteratorPtr DatabaseWithOwnTablesBase::getDictionariesIterator(const Context & /*context*/, const FilterByNameFunction & filter_by_dictionary_name)
|
|
||||||
{
|
|
||||||
std::lock_guard lock(mutex);
|
|
||||||
if (!filter_by_dictionary_name)
|
|
||||||
return std::make_unique<DatabaseDictionariesSnapshotIterator>(dictionaries);
|
|
||||||
|
|
||||||
Dictionaries filtered_dictionaries;
|
|
||||||
for (const auto & dictionary_name : dictionaries)
|
|
||||||
if (filter_by_dictionary_name(dictionary_name))
|
|
||||||
filtered_dictionaries.emplace(dictionary_name);
|
|
||||||
return std::make_unique<DatabaseDictionariesSnapshotIterator>(std::move(filtered_dictionaries));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseWithOwnTablesBase::empty(const Context & /*context*/) const
|
bool DatabaseWithOwnTablesBase::empty(const Context & /*context*/) const
|
||||||
{
|
{
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
@ -140,11 +70,11 @@ StoragePtr DatabaseWithOwnTablesBase::detachTable(const String & table_name)
|
|||||||
{
|
{
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
if (dictionaries.count(table_name))
|
if (dictionaries.count(table_name))
|
||||||
throw Exception("Cannot detach dictionary " + name + "." + table_name + " as table, use DETACH DICTIONARY query.", ErrorCodes::UNKNOWN_TABLE);
|
throw Exception("Cannot detach dictionary " + database_name + "." + table_name + " as table, use DETACH DICTIONARY query.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
|
|
||||||
auto it = tables.find(table_name);
|
auto it = tables.find(table_name);
|
||||||
if (it == tables.end())
|
if (it == tables.end())
|
||||||
throw Exception("Table " + backQuote(name) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
throw Exception("Table " + backQuote(database_name) + "." + backQuote(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
||||||
res = it->second;
|
res = it->second;
|
||||||
tables.erase(it);
|
tables.erase(it);
|
||||||
}
|
}
|
||||||
@ -152,44 +82,11 @@ StoragePtr DatabaseWithOwnTablesBase::detachTable(const String & table_name)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWithOwnTablesBase::detachDictionary(const String & dictionary_name, const Context & context)
|
|
||||||
{
|
|
||||||
String full_name = getDatabaseName() + "." + dictionary_name;
|
|
||||||
{
|
|
||||||
std::lock_guard lock(mutex);
|
|
||||||
auto it = dictionaries.find(dictionary_name);
|
|
||||||
if (it == dictionaries.end())
|
|
||||||
throw Exception("Dictionary " + full_name + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE);
|
|
||||||
dictionaries.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ExternalLoader::reloadConfig() will find out that the dictionary's config has been removed
|
|
||||||
/// and therefore it will unload the dictionary.
|
|
||||||
const auto & external_loader = context.getExternalDictionariesLoader();
|
|
||||||
external_loader.reloadConfig(getDatabaseName(), full_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseWithOwnTablesBase::attachTable(const String & table_name, const StoragePtr & table)
|
void DatabaseWithOwnTablesBase::attachTable(const String & table_name, const StoragePtr & table)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
if (!tables.emplace(table_name, table).second)
|
if (!tables.emplace(table_name, table).second)
|
||||||
throw Exception("Table " + name + "." + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
throw Exception("Table " + database_name + "." + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DatabaseWithOwnTablesBase::attachDictionary(const String & dictionary_name, const Context & context)
|
|
||||||
{
|
|
||||||
String full_name = getDatabaseName() + "." + dictionary_name;
|
|
||||||
{
|
|
||||||
std::lock_guard lock(mutex);
|
|
||||||
if (!dictionaries.emplace(dictionary_name).second)
|
|
||||||
throw Exception("Dictionary " + full_name + " already exists.", ErrorCodes::DICTIONARY_ALREADY_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ExternalLoader::reloadConfig() will find out that the dictionary's config has been added
|
|
||||||
/// and in case `dictionaries_lazy_load == false` it will load the dictionary.
|
|
||||||
const auto & external_loader = context.getExternalDictionariesLoader();
|
|
||||||
external_loader.reloadConfig(getDatabaseName(), full_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWithOwnTablesBase::shutdown()
|
void DatabaseWithOwnTablesBase::shutdown()
|
||||||
@ -217,7 +114,7 @@ DatabaseWithOwnTablesBase::~DatabaseWithOwnTablesBase()
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
shutdown();
|
DatabaseWithOwnTablesBase::shutdown();
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -23,8 +23,6 @@ public:
|
|||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) const override;
|
const String & table_name) const override;
|
||||||
|
|
||||||
bool isDictionaryExist(const Context & context, const String & dictionary_name) const override;
|
|
||||||
|
|
||||||
StoragePtr tryGetTable(
|
StoragePtr tryGetTable(
|
||||||
const Context & context,
|
const Context & context,
|
||||||
const String & table_name) const override;
|
const String & table_name) const override;
|
||||||
@ -33,30 +31,21 @@ public:
|
|||||||
|
|
||||||
void attachTable(const String & table_name, const StoragePtr & table) override;
|
void attachTable(const String & table_name, const StoragePtr & table) override;
|
||||||
|
|
||||||
void attachDictionary(const String & name, const Context & context) override;
|
|
||||||
|
|
||||||
StoragePtr detachTable(const String & table_name) override;
|
StoragePtr detachTable(const String & table_name) override;
|
||||||
|
|
||||||
void detachDictionary(const String & name, const Context & context) override;
|
|
||||||
|
|
||||||
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) override;
|
||||||
|
|
||||||
DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name = {}) override;
|
|
||||||
|
|
||||||
DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name = {}) override;
|
|
||||||
|
|
||||||
void shutdown() override;
|
void shutdown() override;
|
||||||
|
|
||||||
virtual ~DatabaseWithOwnTablesBase() override;
|
virtual ~DatabaseWithOwnTablesBase() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String name;
|
|
||||||
|
|
||||||
mutable std::mutex mutex;
|
mutable std::mutex mutex;
|
||||||
Tables tables;
|
Tables tables;
|
||||||
Dictionaries dictionaries;
|
Dictionaries dictionaries;
|
||||||
|
Poco::Logger * log;
|
||||||
|
|
||||||
DatabaseWithOwnTablesBase(String name_) : name(std::move(name_)) { }
|
DatabaseWithOwnTablesBase(const String & name_, const String & logger);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,15 @@ struct ConstraintsDescription;
|
|||||||
class ColumnsDescription;
|
class ColumnsDescription;
|
||||||
struct IndicesDescription;
|
struct IndicesDescription;
|
||||||
struct TableStructureWriteLockHolder;
|
struct TableStructureWriteLockHolder;
|
||||||
|
class ASTCreateQuery;
|
||||||
using Dictionaries = std::set<String>;
|
using Dictionaries = std::set<String>;
|
||||||
|
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
extern const int NOT_IMPLEMENTED;
|
extern const int NOT_IMPLEMENTED;
|
||||||
|
extern const int CANNOT_GET_CREATE_TABLE_QUERY;
|
||||||
|
extern const int CANNOT_GET_CREATE_TABLE_QUERY;
|
||||||
|
extern const int CANNOT_GET_CREATE_DICTIONARY_QUERY;
|
||||||
}
|
}
|
||||||
|
|
||||||
class IDatabaseTablesIterator
|
class IDatabaseTablesIterator
|
||||||
@ -97,14 +101,15 @@ using DatabaseDictionariesIteratorPtr = std::unique_ptr<DatabaseDictionariesSnap
|
|||||||
class IDatabase : public std::enable_shared_from_this<IDatabase>
|
class IDatabase : public std::enable_shared_from_this<IDatabase>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
IDatabase() = delete;
|
||||||
|
IDatabase(String database_name_) : database_name(std::move(database_name_)) {}
|
||||||
|
|
||||||
/// Get name of database engine.
|
/// Get name of database engine.
|
||||||
virtual String getEngineName() const = 0;
|
virtual String getEngineName() const = 0;
|
||||||
|
|
||||||
/// Load a set of existing tables.
|
/// Load a set of existing tables.
|
||||||
/// You can call only once, right after the object is created.
|
/// You can call only once, right after the object is created.
|
||||||
virtual void loadStoredObjects(
|
virtual void loadStoredObjects(Context & /*context*/, bool /*has_force_restore_data_flag*/) {}
|
||||||
Context & context,
|
|
||||||
bool has_force_restore_data_flag) = 0;
|
|
||||||
|
|
||||||
/// Check the existence of the table.
|
/// Check the existence of the table.
|
||||||
virtual bool isTableExist(
|
virtual bool isTableExist(
|
||||||
@ -113,8 +118,11 @@ public:
|
|||||||
|
|
||||||
/// Check the existence of the dictionary
|
/// Check the existence of the dictionary
|
||||||
virtual bool isDictionaryExist(
|
virtual bool isDictionaryExist(
|
||||||
const Context & context,
|
const Context & /*context*/,
|
||||||
const String & name) const = 0;
|
const String & /*name*/) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the table for work. Return nullptr if there is no table.
|
/// Get the table for work. Return nullptr if there is no table.
|
||||||
virtual StoragePtr tryGetTable(
|
virtual StoragePtr tryGetTable(
|
||||||
@ -128,7 +136,10 @@ public:
|
|||||||
virtual DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) = 0;
|
virtual DatabaseTablesIteratorPtr getTablesIterator(const Context & context, const FilterByNameFunction & filter_by_table_name = {}) = 0;
|
||||||
|
|
||||||
/// Get an iterator to pass through all the dictionaries.
|
/// Get an iterator to pass through all the dictionaries.
|
||||||
virtual DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name = {}) = 0;
|
virtual DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & /*context*/, [[maybe_unused]] const FilterByNameFunction & filter_by_dictionary_name = {})
|
||||||
|
{
|
||||||
|
return std::make_unique<DatabaseDictionariesSnapshotIterator>();
|
||||||
|
}
|
||||||
|
|
||||||
/// Get an iterator to pass through all the tables and dictionary tables.
|
/// Get an iterator to pass through all the tables and dictionary tables.
|
||||||
virtual DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_name = {})
|
virtual DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_name = {})
|
||||||
@ -141,39 +152,63 @@ public:
|
|||||||
|
|
||||||
/// Add the table to the database. Record its presence in the metadata.
|
/// Add the table to the database. Record its presence in the metadata.
|
||||||
virtual void createTable(
|
virtual void createTable(
|
||||||
const Context & context,
|
const Context & /*context*/,
|
||||||
const String & name,
|
const String & /*name*/,
|
||||||
const StoragePtr & table,
|
const StoragePtr & /*table*/,
|
||||||
const ASTPtr & query) = 0;
|
const ASTPtr & /*query*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no CREATE TABLE query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Add the dictionary to the database. Record its presence in the metadata.
|
/// Add the dictionary to the database. Record its presence in the metadata.
|
||||||
virtual void createDictionary(
|
virtual void createDictionary(
|
||||||
const Context & context,
|
const Context & /*context*/,
|
||||||
const String & dictionary_name,
|
const String & /*dictionary_name*/,
|
||||||
const ASTPtr & query) = 0;
|
const ASTPtr & /*query*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no CREATE DICTIONARY query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Delete the table from the database. Delete the metadata.
|
/// Delete the table from the database. Delete the metadata.
|
||||||
virtual void removeTable(
|
virtual void removeTable(
|
||||||
const Context & context,
|
const Context & /*context*/,
|
||||||
const String & name) = 0;
|
const String & /*name*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no DROP TABLE query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Delete the dictionary from the database. Delete the metadata.
|
/// Delete the dictionary from the database. Delete the metadata.
|
||||||
virtual void removeDictionary(
|
virtual void removeDictionary(
|
||||||
const Context & context,
|
const Context & /*context*/,
|
||||||
const String & dictionary_name) = 0;
|
const String & /*dictionary_name*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no DROP DICTIONARY query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a table to the database, but do not add it to the metadata. The database may not support this method.
|
/// Add a table to the database, but do not add it to the metadata. The database may not support this method.
|
||||||
virtual void attachTable(const String & name, const StoragePtr & table) = 0;
|
virtual void attachTable(const String & /*name*/, const StoragePtr & /*table*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no ATTACH TABLE query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Add dictionary to the database, but do not add it to the metadata. The database may not support this method.
|
/// Add dictionary to the database, but do not add it to the metadata. The database may not support this method.
|
||||||
/// If dictionaries_lazy_load is false it also starts loading the dictionary asynchronously.
|
/// If dictionaries_lazy_load is false it also starts loading the dictionary asynchronously.
|
||||||
virtual void attachDictionary(const String & name, const Context & context) = 0;
|
virtual void attachDictionary(const String & /*name*/, const Context & /*context*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no ATTACH DICTIONARY query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Forget about the table without deleting it, and return it. The database may not support this method.
|
/// Forget about the table without deleting it, and return it. The database may not support this method.
|
||||||
virtual StoragePtr detachTable(const String & name) = 0;
|
virtual StoragePtr detachTable(const String & /*name*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no DETACH TABLE query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Forget about the dictionary without deleting it. The database may not support this method.
|
/// Forget about the dictionary without deleting it. The database may not support this method.
|
||||||
virtual void detachDictionary(const String & name, const Context & context) = 0;
|
virtual void detachDictionary(const String & /*name*/, const Context & /*context*/)
|
||||||
|
{
|
||||||
|
throw Exception("There is no DETACH DICTIONARY query for Database" + getEngineName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
/// Rename the table and possibly move the table to another database.
|
/// Rename the table and possibly move the table to another database.
|
||||||
virtual void renameTable(
|
virtual void renameTable(
|
||||||
@ -199,33 +234,44 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns time of table's metadata change, 0 if there is no corresponding metadata file.
|
/// Returns time of table's metadata change, 0 if there is no corresponding metadata file.
|
||||||
virtual time_t getObjectMetadataModificationTime(
|
virtual time_t getObjectMetadataModificationTime(const String & /*name*/) const
|
||||||
const Context & context,
|
{
|
||||||
const String & name) = 0;
|
return static_cast<time_t>(0);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the CREATE TABLE query for the table. It can also provide information for detached tables for which there is metadata.
|
/// Get the CREATE TABLE query for the table. It can also provide information for detached tables for which there is metadata.
|
||||||
virtual ASTPtr tryGetCreateTableQuery(const Context & context, const String & name) const = 0;
|
ASTPtr tryGetCreateTableQuery(const Context & context, const String & name) const noexcept
|
||||||
|
|
||||||
virtual ASTPtr getCreateTableQuery(const Context & context, const String & name) const
|
|
||||||
{
|
{
|
||||||
return tryGetCreateTableQuery(context, name);
|
return getCreateTableQueryImpl(context, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTPtr getCreateTableQuery(const Context & context, const String & name) const
|
||||||
|
{
|
||||||
|
return getCreateTableQueryImpl(context, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the CREATE DICTIONARY query for the dictionary. Returns nullptr if dictionary doesn't exists.
|
/// Get the CREATE DICTIONARY query for the dictionary. Returns nullptr if dictionary doesn't exists.
|
||||||
virtual ASTPtr tryGetCreateDictionaryQuery(const Context & context, const String & name) const = 0;
|
ASTPtr tryGetCreateDictionaryQuery(const Context & context, const String & name) const noexcept
|
||||||
|
|
||||||
virtual ASTPtr getCreateDictionaryQuery(const Context & context, const String & name) const
|
|
||||||
{
|
{
|
||||||
return tryGetCreateDictionaryQuery(context, name);
|
return getCreateDictionaryQueryImpl(context, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTPtr getCreateDictionaryQuery(const Context & context, const String & name) const
|
||||||
|
{
|
||||||
|
return getCreateDictionaryQueryImpl(context, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the CREATE DATABASE query for current database.
|
/// Get the CREATE DATABASE query for current database.
|
||||||
virtual ASTPtr getCreateDatabaseQuery(const Context & context) const = 0;
|
virtual ASTPtr getCreateDatabaseQuery() const = 0;
|
||||||
|
|
||||||
/// Get name of database.
|
/// Get name of database.
|
||||||
virtual String getDatabaseName() const = 0;
|
String getDatabaseName() const { return database_name; }
|
||||||
/// Returns path for persistent data storage if the database supports it, empty string otherwise
|
/// Returns path for persistent data storage if the database supports it, empty string otherwise
|
||||||
virtual String getDataPath() const { return {}; }
|
virtual String getDataPath() const { return {}; }
|
||||||
|
/// Returns path for persistent data storage for table if the database supports it, empty string otherwise. Table must exist
|
||||||
|
virtual String getTableDataPath(const String & /*table_name*/) const { return {}; }
|
||||||
|
/// Returns path for persistent data storage for CREATE/ATTACH query if the database supports it, empty string otherwise
|
||||||
|
virtual String getTableDataPath(const ASTCreateQuery & /*query*/) const { return {}; }
|
||||||
/// Returns metadata path if the database supports it, empty string otherwise
|
/// Returns metadata path if the database supports it, empty string otherwise
|
||||||
virtual String getMetadataPath() const { return {}; }
|
virtual String getMetadataPath() const { return {}; }
|
||||||
/// Returns metadata path of a concrete table if the database supports it, empty string otherwise
|
/// Returns metadata path of a concrete table if the database supports it, empty string otherwise
|
||||||
@ -238,6 +284,23 @@ public:
|
|||||||
virtual void drop(const Context & /*context*/) {}
|
virtual void drop(const Context & /*context*/) {}
|
||||||
|
|
||||||
virtual ~IDatabase() {}
|
virtual ~IDatabase() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ASTPtr getCreateTableQueryImpl(const Context & /*context*/, const String & /*name*/, bool throw_on_error) const
|
||||||
|
{
|
||||||
|
if (throw_on_error)
|
||||||
|
throw Exception("There is no SHOW CREATE TABLE query for Database" + getEngineName(), ErrorCodes::CANNOT_GET_CREATE_TABLE_QUERY);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ASTPtr getCreateDictionaryQueryImpl(const Context & /*context*/, const String & /*name*/, bool throw_on_error) const
|
||||||
|
{
|
||||||
|
if (throw_on_error)
|
||||||
|
throw Exception("There is no SHOW CREATE DICTIONARY query for Database" + getEngineName(), ErrorCodes::CANNOT_GET_CREATE_DICTIONARY_QUERY);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
String database_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
using DatabasePtr = std::shared_ptr<IDatabase>;
|
using DatabasePtr = std::shared_ptr<IDatabase>;
|
||||||
|
@ -316,7 +316,7 @@ BlockInputStreamPtr MongoDBDictionarySource::loadKeys(const Columns & key_column
|
|||||||
|
|
||||||
case AttributeUnderlyingType::utFloat32:
|
case AttributeUnderlyingType::utFloat32:
|
||||||
case AttributeUnderlyingType::utFloat64:
|
case AttributeUnderlyingType::utFloat64:
|
||||||
key.add(attr.second.name, applyVisitor(FieldVisitorConvertToNumber<Float64>(), (*key_columns[attr.first])[row_idx]));
|
key.add(attr.second.name, key_columns[attr.first]->getFloat64(row_idx));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AttributeUnderlyingType::utString:
|
case AttributeUnderlyingType::utString:
|
||||||
|
@ -208,6 +208,30 @@ StoragePolicy::StoragePolicy(String name_, Volumes volumes_, double move_factor_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool StoragePolicy::isDefaultPolicy() const
|
||||||
|
{
|
||||||
|
/// Guessing if this policy is default, not 100% correct though.
|
||||||
|
|
||||||
|
if (getName() != "default")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (volumes.size() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (volumes[0]->getName() != "default")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto & disks = volumes[0]->disks;
|
||||||
|
if (disks.size() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (disks[0]->getName() != "default")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Disks StoragePolicy::getDisks() const
|
Disks StoragePolicy::getDisks() const
|
||||||
{
|
{
|
||||||
Disks res;
|
Disks res;
|
||||||
|
@ -103,6 +103,8 @@ public:
|
|||||||
|
|
||||||
StoragePolicy(String name_, Volumes volumes_, double move_factor_);
|
StoragePolicy(String name_, Volumes volumes_, double move_factor_);
|
||||||
|
|
||||||
|
bool isDefaultPolicy() const;
|
||||||
|
|
||||||
/// Returns disks ordered by volumes priority
|
/// Returns disks ordered by volumes priority
|
||||||
Disks getDisks() const;
|
Disks getDisks() const;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <DataTypes/DataTypeString.h>
|
#include <DataTypes/DataTypeString.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionStringOrArrayToT.h>
|
#include <Functions/FunctionStringOrArrayToT.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <DataTypes/DataTypeString.h>
|
#include <DataTypes/DataTypeString.h>
|
||||||
#include <Common/getFQDNOrHostName.h>
|
#include <Common/getFQDNOrHostName.h>
|
||||||
#include <Core/Field.h>
|
#include <Core/Field.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <Functions/IFunctionAdaptors.h>
|
#include <Functions/IFunctionAdaptors.h>
|
||||||
#include <Common/IFactoryWithAliases.h>
|
#include <Common/IFactoryWithAliases.h>
|
||||||
#include "URL/registerFunctionsURL.h"
|
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <Interpreters/Join.h>
|
#include <Interpreters/Join.h>
|
||||||
#include <Storages/StorageJoin.h>
|
#include <Storages/StorageJoin.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
// TODO include this last because of a broken roaring header. See the comment
|
// TODO include this last because of a broken roaring header. See the comment
|
||||||
// inside.
|
// inside.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsCoding.h>
|
#include <Functions/FunctionsCoding.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsConversion.h>
|
#include <Functions/FunctionsConversion.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "FunctionFactory.h"
|
#include "FunctionFactory.h"
|
||||||
#include "FunctionsEmbeddedDictionaries.h"
|
#include "FunctionsEmbeddedDictionaries.h"
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsExternalDictionaries.h>
|
#include <Functions/FunctionsExternalDictionaries.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <Columns/ColumnTuple.h>
|
#include <Columns/ColumnTuple.h>
|
||||||
#include <DataTypes/DataTypeTuple.h>
|
#include <DataTypes/DataTypeTuple.h>
|
||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsFindCluster.h>
|
#include <Functions/FunctionsFindCluster.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsFormatting.h>
|
#include <Functions/FunctionsFormatting.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "FunctionsHashing.h"
|
#include "FunctionsHashing.h"
|
||||||
|
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <Functions/FunctionsJSON.h>
|
#include <Functions/FunctionsJSON.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <Common/HashTable/Hash.h>
|
#include <Common/HashTable/Hash.h>
|
||||||
#include <Common/randomSeed.h>
|
#include <Common/randomSeed.h>
|
||||||
#include <common/unaligned.h>
|
#include <common/unaligned.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsReinterpret.h>
|
#include <Functions/FunctionsReinterpret.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsRound.h>
|
#include <Functions/FunctionsRound.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsStringArray.h>
|
#include <Functions/FunctionsStringArray.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#include "FunctionsStringRegex.h"
|
#include "FunctionsStringRegex.h"
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
#include "FunctionsStringSearch.h"
|
#include "FunctionsStringSearch.h"
|
||||||
#include <Columns/ColumnFixedString.h>
|
#include <Columns/ColumnFixedString.h>
|
||||||
#include <DataTypes/DataTypeFixedString.h>
|
#include <DataTypes/DataTypeFixedString.h>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "FunctionsStringSearch.h"
|
#include "FunctionsStringSearch.h"
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#include <Functions/FunctionsStringSimilarity.h>
|
#include <Functions/FunctionsStringSimilarity.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionsHashing.h>
|
#include <Functions/FunctionsHashing.h>
|
||||||
#include <Common/HashTable/ClearableHashMap.h>
|
#include <Common/HashTable/ClearableHashMap.h>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionStringToString.h>
|
#include <Functions/FunctionStringToString.h>
|
||||||
#include <Functions/registerFunctions.h>
|
|
||||||
#include <common/find_symbols.h>
|
#include <common/find_symbols.h>
|
||||||
#include "FunctionsURL.h"
|
#include "FunctionsURL.h"
|
||||||
|
|
||||||
|
@ -1,8 +1,31 @@
|
|||||||
#include "registerFunctionsURL.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class FunctionFactory;
|
||||||
|
|
||||||
|
void registerFunctionProtocol(FunctionFactory & factory);
|
||||||
|
void registerFunctionDomain(FunctionFactory & factory);
|
||||||
|
void registerFunctionDomainWithoutWWW(FunctionFactory & factory);
|
||||||
|
void registerFunctionFirstSignificantSubdomain(FunctionFactory & factory);
|
||||||
|
void registerFunctionTopLevelDomain(FunctionFactory & factory);
|
||||||
|
void registerFunctionPath(FunctionFactory & factory);
|
||||||
|
void registerFunctionPathFull(FunctionFactory & factory);
|
||||||
|
void registerFunctionQueryString(FunctionFactory & factory);
|
||||||
|
void registerFunctionFragment(FunctionFactory & factory);
|
||||||
|
void registerFunctionQueryStringAndFragment(FunctionFactory & factory);
|
||||||
|
void registerFunctionExtractURLParameter(FunctionFactory & factory);
|
||||||
|
void registerFunctionExtractURLParameters(FunctionFactory & factory);
|
||||||
|
void registerFunctionExtractURLParameterNames(FunctionFactory & factory);
|
||||||
|
void registerFunctionURLHierarchy(FunctionFactory & factory);
|
||||||
|
void registerFunctionURLPathHierarchy(FunctionFactory & factory);
|
||||||
|
void registerFunctionCutToFirstSignificantSubdomain(FunctionFactory & factory);
|
||||||
|
void registerFunctionCutWWW(FunctionFactory & factory);
|
||||||
|
void registerFunctionCutQueryString(FunctionFactory & factory);
|
||||||
|
void registerFunctionCutFragment(FunctionFactory & factory);
|
||||||
|
void registerFunctionCutQueryStringAndFragment(FunctionFactory & factory);
|
||||||
|
void registerFunctionCutURLParameter(FunctionFactory & factory);
|
||||||
|
void registerFunctionDecodeURLComponent(FunctionFactory & factory);
|
||||||
|
|
||||||
void registerFunctionsURL(FunctionFactory & factory)
|
void registerFunctionsURL(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
registerFunctionProtocol(factory);
|
registerFunctionProtocol(factory);
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace DB
|
|
||||||
{
|
|
||||||
class FunctionFactory;
|
|
||||||
|
|
||||||
void registerFunctionProtocol(FunctionFactory &);
|
|
||||||
void registerFunctionDomain(FunctionFactory &);
|
|
||||||
void registerFunctionDomainWithoutWWW(FunctionFactory &);
|
|
||||||
void registerFunctionFirstSignificantSubdomain(FunctionFactory &);
|
|
||||||
void registerFunctionTopLevelDomain(FunctionFactory &);
|
|
||||||
void registerFunctionPath(FunctionFactory &);
|
|
||||||
void registerFunctionPathFull(FunctionFactory &);
|
|
||||||
void registerFunctionQueryString(FunctionFactory &);
|
|
||||||
void registerFunctionFragment(FunctionFactory &);
|
|
||||||
void registerFunctionQueryStringAndFragment(FunctionFactory &);
|
|
||||||
void registerFunctionExtractURLParameter(FunctionFactory &);
|
|
||||||
void registerFunctionExtractURLParameters(FunctionFactory &);
|
|
||||||
void registerFunctionExtractURLParameterNames(FunctionFactory &);
|
|
||||||
void registerFunctionURLHierarchy(FunctionFactory &);
|
|
||||||
void registerFunctionURLPathHierarchy(FunctionFactory &);
|
|
||||||
void registerFunctionCutToFirstSignificantSubdomain(FunctionFactory &);
|
|
||||||
void registerFunctionCutWWW(FunctionFactory &);
|
|
||||||
void registerFunctionCutQueryString(FunctionFactory &);
|
|
||||||
void registerFunctionCutFragment(FunctionFactory &);
|
|
||||||
void registerFunctionCutQueryStringAndFragment(FunctionFactory &);
|
|
||||||
void registerFunctionCutURLParameter(FunctionFactory &);
|
|
||||||
void registerFunctionDecodeURLComponent(FunctionFactory &);
|
|
||||||
|
|
||||||
void registerFunctionsURL(FunctionFactory &);
|
|
||||||
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
#include <Functions/FunctionMathUnary.h>
|
#include <Functions/FunctionMathUnary.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
#include <Functions/FunctionDateOrDateTimeAddInterval.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Interpreters/Context.h>
|
#include <Interpreters/Context.h>
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <Functions/FunctionHelpers.h>
|
#include <Functions/FunctionHelpers.h>
|
||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <ext/range.h>
|
#include <ext/range.h>
|
||||||
#include "registerFunctions.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <DataTypes/getLeastSupertype.h>
|
#include <DataTypes/getLeastSupertype.h>
|
||||||
#include <Columns/ColumnArray.h>
|
#include <Columns/ColumnArray.h>
|
||||||
#include <Interpreters/castColumn.h>
|
#include <Interpreters/castColumn.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <Columns/ColumnDecimal.h>
|
#include <Columns/ColumnDecimal.h>
|
||||||
#include <Functions/array/FunctionArrayMapped.h>
|
#include <Functions/array/FunctionArrayMapped.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <Columns/ColumnConst.h>
|
#include <Columns/ColumnConst.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
#include <ext/range.h>
|
#include <ext/range.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <Columns/ColumnDecimal.h>
|
#include <Columns/ColumnDecimal.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <Columns/ColumnDecimal.h>
|
#include <Columns/ColumnDecimal.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <Columns/ColumnDecimal.h>
|
#include <Columns/ColumnDecimal.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <Common/HashTable/ClearableHashSet.h>
|
#include <Common/HashTable/ClearableHashSet.h>
|
||||||
#include <Common/SipHash.h>
|
#include <Common/SipHash.h>
|
||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <Columns/ColumnTuple.h>
|
#include <Columns/ColumnTuple.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <DataTypes/DataTypesNumber.h>
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
#include <Columns/ColumnArray.h>
|
#include <Columns/ColumnArray.h>
|
||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "arrayEnumerateExtended.h"
|
#include "arrayEnumerateExtended.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "arrayEnumerateRanked.h"
|
#include "arrayEnumerateRanked.h"
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Columns/ColumnConst.h>
|
#include <Columns/ColumnConst.h>
|
||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
#include "arrayEnumerateRanked.h"
|
#include "arrayEnumerateRanked.h"
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "arrayEnumerateExtended.h"
|
#include "arrayEnumerateExtended.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "Functions/FunctionFactory.h"
|
#include "Functions/FunctionFactory.h"
|
||||||
#include "arrayEnumerateRanked.h"
|
#include "arrayEnumerateRanked.h"
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <Functions/FunctionHelpers.h>
|
#include <Functions/FunctionHelpers.h>
|
||||||
#include <DataTypes/DataTypeArray.h>
|
#include <DataTypes/DataTypeArray.h>
|
||||||
#include <Columns/ColumnArray.h>
|
#include <Columns/ColumnArray.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include <Core/TypeListNumber.h>
|
#include <Core/TypeListNumber.h>
|
||||||
#include <Interpreters/castColumn.h>
|
#include <Interpreters/castColumn.h>
|
||||||
#include <ext/range.h>
|
#include <ext/range.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Functions/FunctionHelpers.h>
|
#include <Functions/FunctionHelpers.h>
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <DataTypes/DataTypeArray.h>
|
#include <DataTypes/DataTypeArray.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "arrayPop.h"
|
#include "arrayPop.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "arrayPop.h"
|
#include "arrayPop.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "arrayPush.h"
|
#include "arrayPush.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "arrayPush.h"
|
#include "arrayPush.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <AggregateFunctions/parseAggregateFunctionParameters.h>
|
#include <AggregateFunctions/parseAggregateFunctionParameters.h>
|
||||||
#include <Common/AlignedBuffer.h>
|
#include <Common/AlignedBuffer.h>
|
||||||
#include <Common/Arena.h>
|
#include <Common/Arena.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
#include <ext/scope_guard.h>
|
#include <ext/scope_guard.h>
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <Interpreters/castColumn.h>
|
#include <Interpreters/castColumn.h>
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <Columns/ColumnFixedString.h>
|
#include <Columns/ColumnFixedString.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include <Columns/ColumnConst.h>
|
#include <Columns/ColumnConst.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <Columns/ColumnsNumber.h>
|
#include <Columns/ColumnsNumber.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <Columns/ColumnDecimal.h>
|
#include <Columns/ColumnDecimal.h>
|
||||||
#include "FunctionArrayMapped.h"
|
#include "FunctionArrayMapped.h"
|
||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <Common/ColumnsHashing.h>
|
#include <Common/ColumnsHashing.h>
|
||||||
#include <Interpreters/AggregationCommon.h>
|
#include <Interpreters/AggregationCommon.h>
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <DataTypes/DataTypeArray.h>
|
#include <DataTypes/DataTypeArray.h>
|
||||||
#include <DataTypes/DataTypesNumber.h>
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
#include <Columns/ColumnArray.h>
|
#include <Columns/ColumnArray.h>
|
||||||
#include "registerFunctionsArray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user