Merge remote-tracking branch 'origin/master' into HEAD

This commit is contained in:
Alexander Kuzmenkov 2020-11-23 21:00:22 +03:00
commit 951a59eff7
402 changed files with 2874 additions and 1390 deletions

2
.gitmodules vendored
View File

@ -196,7 +196,7 @@
[submodule "contrib/rocksdb"] [submodule "contrib/rocksdb"]
path = contrib/rocksdb path = contrib/rocksdb
url = https://github.com/facebook/rocksdb url = https://github.com/facebook/rocksdb
branch = v6.11.4 branch = v6.14.5
[submodule "contrib/xz"] [submodule "contrib/xz"]
path = contrib/xz path = contrib/xz
url = https://github.com/xz-mirror/xz url = https://github.com/xz-mirror/xz

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <stdexcept> // for std::logic_error
#include <string> #include <string>
#include <vector> #include <vector>
#include <functional> #include <functional>

View File

@ -1,9 +1,9 @@
# This strings autochanged from release_lib.sh: # This strings autochanged from release_lib.sh:
SET(VERSION_REVISION 54443) SET(VERSION_REVISION 54444)
SET(VERSION_MAJOR 20) SET(VERSION_MAJOR 20)
SET(VERSION_MINOR 12) SET(VERSION_MINOR 13)
SET(VERSION_PATCH 1) SET(VERSION_PATCH 1)
SET(VERSION_GITHASH c53725fb1f846fda074347607ab582fbb9c6f7a1) SET(VERSION_GITHASH e581f9ccfc5c64867b0f488cce72412fd2966471)
SET(VERSION_DESCRIBE v20.12.1.1-prestable) SET(VERSION_DESCRIBE v20.13.1.1-prestable)
SET(VERSION_STRING 20.12.1.1) SET(VERSION_STRING 20.13.1.1)
# end of autochange # end of autochange

2
contrib/cctz vendored

@ -1 +1 @@
Subproject commit 7a2db4ece6e0f1b246173cbdb62711ae258ee841 Subproject commit 260ba195ef6c489968bae8c88c62a67cdac5ff9d

2
contrib/rocksdb vendored

@ -1 +1 @@
Subproject commit 963314ffd681596ef2738a95249fe4c1163ef87a Subproject commit 35d8e36ef1b8e3e0759ca81215f855226a0a54bd

View File

@ -347,8 +347,9 @@ set(SOURCES
${ROCKSDB_SOURCE_DIR}/db/blob/blob_file_builder.cc ${ROCKSDB_SOURCE_DIR}/db/blob/blob_file_builder.cc
${ROCKSDB_SOURCE_DIR}/db/blob/blob_file_garbage.cc ${ROCKSDB_SOURCE_DIR}/db/blob/blob_file_garbage.cc
${ROCKSDB_SOURCE_DIR}/db/blob/blob_file_meta.cc ${ROCKSDB_SOURCE_DIR}/db/blob/blob_file_meta.cc
${ROCKSDB_SOURCE_DIR}/db/blob/blob_file_reader.cc
${ROCKSDB_SOURCE_DIR}/db/blob/blob_log_format.cc ${ROCKSDB_SOURCE_DIR}/db/blob/blob_log_format.cc
${ROCKSDB_SOURCE_DIR}/db/blob/blob_log_reader.cc ${ROCKSDB_SOURCE_DIR}/db/blob/blob_log_sequential_reader.cc
${ROCKSDB_SOURCE_DIR}/db/blob/blob_log_writer.cc ${ROCKSDB_SOURCE_DIR}/db/blob/blob_log_writer.cc
${ROCKSDB_SOURCE_DIR}/db/builder.cc ${ROCKSDB_SOURCE_DIR}/db/builder.cc
${ROCKSDB_SOURCE_DIR}/db/c.cc ${ROCKSDB_SOURCE_DIR}/db/c.cc
@ -394,6 +395,8 @@ set(SOURCES
${ROCKSDB_SOURCE_DIR}/db/memtable_list.cc ${ROCKSDB_SOURCE_DIR}/db/memtable_list.cc
${ROCKSDB_SOURCE_DIR}/db/merge_helper.cc ${ROCKSDB_SOURCE_DIR}/db/merge_helper.cc
${ROCKSDB_SOURCE_DIR}/db/merge_operator.cc ${ROCKSDB_SOURCE_DIR}/db/merge_operator.cc
${ROCKSDB_SOURCE_DIR}/db/output_validator.cc
${ROCKSDB_SOURCE_DIR}/db/periodic_work_scheduler.cc
${ROCKSDB_SOURCE_DIR}/db/range_del_aggregator.cc ${ROCKSDB_SOURCE_DIR}/db/range_del_aggregator.cc
${ROCKSDB_SOURCE_DIR}/db/range_tombstone_fragmenter.cc ${ROCKSDB_SOURCE_DIR}/db/range_tombstone_fragmenter.cc
${ROCKSDB_SOURCE_DIR}/db/repair.cc ${ROCKSDB_SOURCE_DIR}/db/repair.cc
@ -451,12 +454,12 @@ set(SOURCES
${ROCKSDB_SOURCE_DIR}/monitoring/perf_level.cc ${ROCKSDB_SOURCE_DIR}/monitoring/perf_level.cc
${ROCKSDB_SOURCE_DIR}/monitoring/persistent_stats_history.cc ${ROCKSDB_SOURCE_DIR}/monitoring/persistent_stats_history.cc
${ROCKSDB_SOURCE_DIR}/monitoring/statistics.cc ${ROCKSDB_SOURCE_DIR}/monitoring/statistics.cc
${ROCKSDB_SOURCE_DIR}/monitoring/stats_dump_scheduler.cc
${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_impl.cc ${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_impl.cc
${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_updater.cc ${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_updater.cc
${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_util.cc ${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_util.cc
${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_util_debug.cc ${ROCKSDB_SOURCE_DIR}/monitoring/thread_status_util_debug.cc
${ROCKSDB_SOURCE_DIR}/options/cf_options.cc ${ROCKSDB_SOURCE_DIR}/options/cf_options.cc
${ROCKSDB_SOURCE_DIR}/options/configurable.cc
${ROCKSDB_SOURCE_DIR}/options/db_options.cc ${ROCKSDB_SOURCE_DIR}/options/db_options.cc
${ROCKSDB_SOURCE_DIR}/options/options.cc ${ROCKSDB_SOURCE_DIR}/options/options.cc
${ROCKSDB_SOURCE_DIR}/options/options_helper.cc ${ROCKSDB_SOURCE_DIR}/options/options_helper.cc
@ -507,6 +510,7 @@ set(SOURCES
${ROCKSDB_SOURCE_DIR}/table/sst_file_dumper.cc ${ROCKSDB_SOURCE_DIR}/table/sst_file_dumper.cc
${ROCKSDB_SOURCE_DIR}/table/sst_file_reader.cc ${ROCKSDB_SOURCE_DIR}/table/sst_file_reader.cc
${ROCKSDB_SOURCE_DIR}/table/sst_file_writer.cc ${ROCKSDB_SOURCE_DIR}/table/sst_file_writer.cc
${ROCKSDB_SOURCE_DIR}/table/table_factory.cc
${ROCKSDB_SOURCE_DIR}/table/table_properties.cc ${ROCKSDB_SOURCE_DIR}/table/table_properties.cc
${ROCKSDB_SOURCE_DIR}/table/two_level_iterator.cc ${ROCKSDB_SOURCE_DIR}/table/two_level_iterator.cc
${ROCKSDB_SOURCE_DIR}/test_util/sync_point.cc ${ROCKSDB_SOURCE_DIR}/test_util/sync_point.cc
@ -515,6 +519,7 @@ set(SOURCES
${ROCKSDB_SOURCE_DIR}/test_util/transaction_test_util.cc ${ROCKSDB_SOURCE_DIR}/test_util/transaction_test_util.cc
${ROCKSDB_SOURCE_DIR}/tools/block_cache_analyzer/block_cache_trace_analyzer.cc ${ROCKSDB_SOURCE_DIR}/tools/block_cache_analyzer/block_cache_trace_analyzer.cc
${ROCKSDB_SOURCE_DIR}/tools/dump/db_dump_tool.cc ${ROCKSDB_SOURCE_DIR}/tools/dump/db_dump_tool.cc
${ROCKSDB_SOURCE_DIR}/tools/io_tracer_parser_tool.cc
${ROCKSDB_SOURCE_DIR}/tools/ldb_cmd.cc ${ROCKSDB_SOURCE_DIR}/tools/ldb_cmd.cc
${ROCKSDB_SOURCE_DIR}/tools/ldb_tool.cc ${ROCKSDB_SOURCE_DIR}/tools/ldb_tool.cc
${ROCKSDB_SOURCE_DIR}/tools/sst_dump_tool.cc ${ROCKSDB_SOURCE_DIR}/tools/sst_dump_tool.cc

4
debian/changelog vendored
View File

@ -1,5 +1,5 @@
clickhouse (20.12.1.1) unstable; urgency=low clickhouse (20.13.1.1) unstable; urgency=low
* Modified source code * Modified source code
-- clickhouse-release <clickhouse-release@yandex-team.ru> Thu, 05 Nov 2020 21:52:47 +0300 -- clickhouse-release <clickhouse-release@yandex-team.ru> Mon, 23 Nov 2020 10:29:24 +0300

View File

@ -1,7 +1,7 @@
FROM ubuntu:18.04 FROM ubuntu:18.04
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/" ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
ARG version=20.12.1.* ARG version=20.13.1.*
RUN apt-get update \ RUN apt-get update \
&& apt-get install --yes --no-install-recommends \ && apt-get install --yes --no-install-recommends \

View File

@ -1,7 +1,7 @@
FROM ubuntu:20.04 FROM ubuntu:20.04
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/" ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
ARG version=20.12.1.* ARG version=20.13.1.*
ARG gosu_ver=1.10 ARG gosu_ver=1.10
RUN apt-get update \ RUN apt-get update \

View File

@ -1,7 +1,7 @@
FROM ubuntu:18.04 FROM ubuntu:18.04
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/" ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
ARG version=20.12.1.* ARG version=20.13.1.*
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y apt-transport-https dirmngr && \ apt-get install -y apt-transport-https dirmngr && \

View File

@ -7,8 +7,10 @@ ENV SOURCE_DIR=/build
ENV OUTPUT_DIR=/output ENV OUTPUT_DIR=/output
ENV IGNORE='.*contrib.*' ENV IGNORE='.*contrib.*'
CMD mkdir -p /build/obj-x86_64-linux-gnu && cd /build/obj-x86_64-linux-gnu && CC=clang-10 CXX=clang++-10 cmake .. && cd /; \ RUN apt-get update && apt-get install cmake --yes --no-install-recommends
CMD mkdir -p /build/obj-x86_64-linux-gnu && cd /build/obj-x86_64-linux-gnu && CC=clang-11 CXX=clang++-11 cmake .. && cd /; \
dpkg -i /package_folder/clickhouse-common-static_*.deb; \ dpkg -i /package_folder/clickhouse-common-static_*.deb; \
llvm-profdata-10 merge -sparse ${COVERAGE_DIR}/* -o clickhouse.profdata && \ llvm-profdata-11 merge -sparse ${COVERAGE_DIR}/* -o clickhouse.profdata && \
llvm-cov-10 export /usr/bin/clickhouse -instr-profile=clickhouse.profdata -j=16 -format=lcov -skip-functions -ignore-filename-regex $IGNORE > output.lcov && \ llvm-cov-11 export /usr/bin/clickhouse -instr-profile=clickhouse.profdata -j=16 -format=lcov -skip-functions -ignore-filename-regex $IGNORE > output.lcov && \
genhtml output.lcov --ignore-errors source --output-directory ${OUTPUT_DIR} genhtml output.lcov --ignore-errors source --output-directory ${OUTPUT_DIR}

View File

@ -15,6 +15,9 @@ stage=${stage:-}
# empty parameter. # empty parameter.
read -ra FASTTEST_CMAKE_FLAGS <<< "${FASTTEST_CMAKE_FLAGS:-}" read -ra FASTTEST_CMAKE_FLAGS <<< "${FASTTEST_CMAKE_FLAGS:-}"
# Run only matching tests.
FASTTEST_FOCUS=${FASTTEST_FOCUS:-""}
FASTTEST_WORKSPACE=$(readlink -f "${FASTTEST_WORKSPACE:-.}") FASTTEST_WORKSPACE=$(readlink -f "${FASTTEST_WORKSPACE:-.}")
FASTTEST_SOURCE=$(readlink -f "${FASTTEST_SOURCE:-$FASTTEST_WORKSPACE/ch}") FASTTEST_SOURCE=$(readlink -f "${FASTTEST_SOURCE:-$FASTTEST_WORKSPACE/ch}")
FASTTEST_BUILD=$(readlink -f "${FASTTEST_BUILD:-${BUILD:-$FASTTEST_WORKSPACE/build}}") FASTTEST_BUILD=$(readlink -f "${FASTTEST_BUILD:-${BUILD:-$FASTTEST_WORKSPACE/build}}")
@ -291,7 +294,7 @@ TESTS_TO_SKIP=(
01563_distributed_query_finish 01563_distributed_query_finish
) )
time clickhouse-test -j 8 --order=random --no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee "$FASTTEST_OUTPUT/test_log.txt" time clickhouse-test -j 8 --order=random --no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" -- "$FASTTEST_FOCUS" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee "$FASTTEST_OUTPUT/test_log.txt"
# substr is to remove semicolon after test name # substr is to remove semicolon after test name
readarray -t FAILED_TESTS < <(awk '/FAIL|TIMEOUT|ERROR/ { print substr($3, 1, length($3)-1) }' "$FASTTEST_OUTPUT/test_log.txt" | tee "$FASTTEST_OUTPUT/failed-parallel-tests.txt") readarray -t FAILED_TESTS < <(awk '/FAIL|TIMEOUT|ERROR/ { print substr($3, 1, length($3)-1) }' "$FASTTEST_OUTPUT/test_log.txt" | tee "$FASTTEST_OUTPUT/failed-parallel-tests.txt")

View File

@ -30,7 +30,7 @@ RUN apt-get update \
tzdata \ tzdata \
vim \ vim \
wget \ wget \
&& pip3 --no-cache-dir install clickhouse_driver scipy \ && pip3 --no-cache-dir install 'clickhouse-driver>=0.1.5' scipy \
&& apt-get purge --yes python3-dev g++ \ && apt-get purge --yes python3-dev g++ \
&& apt-get autoremove --yes \ && apt-get autoremove --yes \
&& apt-get clean \ && apt-get clean \

View File

@ -14,10 +14,12 @@ import string
import sys import sys
import time import time
import traceback import traceback
import logging
import xml.etree.ElementTree as et import xml.etree.ElementTree as et
from threading import Thread from threading import Thread
from scipy import stats from scipy import stats
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(module)s: %(message)s', level='WARNING')
total_start_seconds = time.perf_counter() total_start_seconds = time.perf_counter()
stage_start_seconds = total_start_seconds stage_start_seconds = total_start_seconds
@ -171,12 +173,9 @@ reportStageEnd('drop-1')
settings = root.findall('settings/*') settings = root.findall('settings/*')
for conn_index, c in enumerate(all_connections): for conn_index, c in enumerate(all_connections):
for s in settings: for s in settings:
try: # requires clickhouse-driver >= 1.1.5 to accept arbitrary new settings
q = f"set {s.tag} = '{s.text}'" # (https://github.com/mymarilyn/clickhouse-driver/pull/142)
c.execute(q) c.settings[s.tag] = s.text
print(f'set\t{conn_index}\t{c.last_query.elapsed}\t{tsv_escape(q)}')
except:
print(traceback.format_exc(), file=sys.stderr)
reportStageEnd('settings') reportStageEnd('settings')

View File

@ -1,12 +1,12 @@
# docker build -t yandex/clickhouse-stateful-test-with-coverage . # docker build -t yandex/clickhouse-stateful-test-with-coverage .
FROM yandex/clickhouse-stateless-test FROM yandex/clickhouse-stateless-test-with-coverage
RUN echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main" >> /etc/apt/sources.list RUN echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main" >> /etc/apt/sources.list
RUN apt-get update -y \ RUN apt-get update -y \
&& env DEBIAN_FRONTEND=noninteractive \ && env DEBIAN_FRONTEND=noninteractive \
apt-get install --yes --no-install-recommends \ apt-get install --yes --no-install-recommends \
python3-requests python3-requests procps psmisc
COPY s3downloader /s3downloader COPY s3downloader /s3downloader
COPY run.sh /run.sh COPY run.sh /run.sh

View File

@ -1,40 +1,44 @@
#!/bin/bash #!/bin/bash
kill_clickhouse () { kill_clickhouse () {
kill "$(pgrep -u clickhouse)" 2>/dev/null echo "clickhouse pids $(pgrep -u clickhouse)" | ts '%Y-%m-%d %H:%M:%S'
pkill -f "clickhouse-server" 2>/dev/null
for _ in {1..10}
for _ in {1..120}
do do
if ! kill -0 "$(pgrep -u clickhouse)"; then if ! pkill -0 -f "clickhouse-server" ; then break ; fi
echo "No clickhouse process" echo "ClickHouse still alive" | ts '%Y-%m-%d %H:%M:%S'
break sleep 1
else
echo "Process $(pgrep -u clickhouse) still alive"
sleep 10
fi
done done
if pkill -0 -f "clickhouse-server"
then
pstree -apgT
jobs
echo "Failed to kill the ClickHouse server" | ts '%Y-%m-%d %H:%M:%S'
return 1
fi
} }
start_clickhouse () { start_clickhouse () {
LLVM_PROFILE_FILE='server_%h_%p_%m.profraw' sudo -Eu clickhouse /usr/bin/clickhouse-server --config /etc/clickhouse-server/config.xml & LLVM_PROFILE_FILE='server_%h_%p_%m.profraw' sudo -Eu clickhouse /usr/bin/clickhouse-server --config /etc/clickhouse-server/config.xml &
} counter=0
until clickhouse-client --query "SELECT 1"
wait_llvm_profdata () {
while kill -0 "$(pgrep llvm-profdata-10)"
do do
echo "Waiting for profdata $(pgrep llvm-profdata-10) still alive" if [ "$counter" -gt 120 ]
sleep 3 then
echo "Cannot start clickhouse-server"
cat /var/log/clickhouse-server/stdout.log
tail -n1000 /var/log/clickhouse-server/stderr.log
tail -n1000 /var/log/clickhouse-server/clickhouse-server.log
break
fi
sleep 0.5
counter=$((counter + 1))
done done
} }
merge_client_files_in_background () {
client_files=$(ls /client_*profraw 2>/dev/null)
if [ -n "$client_files" ]
then
llvm-profdata-10 merge -sparse "$client_files" -o "merged_client_$(date +%s).profraw"
rm "$client_files"
fi
}
chmod 777 / chmod 777 /
@ -51,26 +55,7 @@ chmod 777 -R /var/log/clickhouse-server/
# install test configs # install test configs
/usr/share/clickhouse-test/config/install.sh /usr/share/clickhouse-test/config/install.sh
function start() start_clickhouse
{
counter=0
until clickhouse-client --query "SELECT 1"
do
if [ "$counter" -gt 120 ]
then
echo "Cannot start clickhouse-server"
cat /var/log/clickhouse-server/stdout.log
tail -n1000 /var/log/clickhouse-server/stderr.log
tail -n1000 /var/log/clickhouse-server/clickhouse-server.log
break
fi
timeout 120 service clickhouse-server start
sleep 0.5
counter=$((counter + 1))
done
}
start
# shellcheck disable=SC2086 # No quotes because I want to split it into words. # shellcheck disable=SC2086 # No quotes because I want to split it into words.
if ! /s3downloader --dataset-names $DATASETS; then if ! /s3downloader --dataset-names $DATASETS; then
@ -81,25 +66,20 @@ fi
chmod 777 -R /var/lib/clickhouse chmod 777 -R /var/lib/clickhouse
while /bin/true; do
merge_client_files_in_background
sleep 2
done &
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "SHOW DATABASES" LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "SHOW DATABASES"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "ATTACH DATABASE datasets ENGINE = Ordinary" LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "ATTACH DATABASE datasets ENGINE = Ordinary"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "CREATE DATABASE test" LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "CREATE DATABASE test"
kill_clickhouse kill_clickhouse
start_clickhouse start_clickhouse
sleep 10 LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "SHOW TABLES FROM datasets"
LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "SHOW TABLES FROM test"
LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "RENAME TABLE datasets.hits_v1 TO test.hits"
LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "RENAME TABLE datasets.visits_v1 TO test.visits"
LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-client --query "SHOW TABLES FROM test"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "SHOW TABLES FROM datasets"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "SHOW TABLES FROM test"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "RENAME TABLE datasets.hits_v1 TO test.hits"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "RENAME TABLE datasets.visits_v1 TO test.visits"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-client --query "SHOW TABLES FROM test"
if grep -q -- "--use-skip-list" /usr/bin/clickhouse-test; then if grep -q -- "--use-skip-list" /usr/bin/clickhouse-test; then
SKIP_LIST_OPT="--use-skip-list" SKIP_LIST_OPT="--use-skip-list"
@ -109,15 +89,10 @@ fi
# more idiologically correct. # more idiologically correct.
read -ra ADDITIONAL_OPTIONS <<< "${ADDITIONAL_OPTIONS:-}" read -ra ADDITIONAL_OPTIONS <<< "${ADDITIONAL_OPTIONS:-}"
LLVM_PROFILE_FILE='client_%h_%p_%m.profraw' clickhouse-test --testname --shard --zookeeper --no-stateless --hung-check --print-time "$SKIP_LIST_OPT" "${ADDITIONAL_OPTIONS[@]}" "$SKIP_TESTS_OPTION" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee test_output/test_result.txt LLVM_PROFILE_FILE='client_coverage.profraw' clickhouse-test --testname --shard --zookeeper --no-stateless --hung-check --print-time "$SKIP_LIST_OPT" "${ADDITIONAL_OPTIONS[@]}" "$SKIP_TESTS_OPTION" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee test_output/test_result.txt
kill_clickhouse kill_clickhouse
wait_llvm_profdata
sleep 3 sleep 3
wait_llvm_profdata # 100% merged all parts
cp /*.profraw /profraw ||: cp /*.profraw /profraw ||:

View File

@ -1,4 +1,4 @@
# docker build -t yandex/clickhouse-stateless-with-coverage-test . # docker build -t yandex/clickhouse-stateless-test-with-coverage .
# TODO: that can be based on yandex/clickhouse-stateless-test (llvm version and CMD differs) # TODO: that can be based on yandex/clickhouse-stateless-test (llvm version and CMD differs)
FROM yandex/clickhouse-test-base FROM yandex/clickhouse-test-base
@ -28,7 +28,9 @@ RUN apt-get update -y \
lsof \ lsof \
unixodbc \ unixodbc \
wget \ wget \
qemu-user-static qemu-user-static \
procps \
psmisc
RUN mkdir -p /tmp/clickhouse-odbc-tmp \ RUN mkdir -p /tmp/clickhouse-odbc-tmp \
&& wget -nv -O - ${odbc_driver_url} | tar --strip-components=1 -xz -C /tmp/clickhouse-odbc-tmp \ && wget -nv -O - ${odbc_driver_url} | tar --strip-components=1 -xz -C /tmp/clickhouse-odbc-tmp \

View File

@ -2,27 +2,41 @@
kill_clickhouse () { kill_clickhouse () {
echo "clickhouse pids $(pgrep -u clickhouse)" | ts '%Y-%m-%d %H:%M:%S' echo "clickhouse pids $(pgrep -u clickhouse)" | ts '%Y-%m-%d %H:%M:%S'
kill "$(pgrep -u clickhouse)" 2>/dev/null pkill -f "clickhouse-server" 2>/dev/null
for _ in {1..10}
for _ in {1..120}
do do
if ! kill -0 "$(pgrep -u clickhouse)"; then if ! pkill -0 -f "clickhouse-server" ; then break ; fi
echo "No clickhouse process" | ts '%Y-%m-%d %H:%M:%S' echo "ClickHouse still alive" | ts '%Y-%m-%d %H:%M:%S'
break sleep 1
else
echo "Process $(pgrep -u clickhouse) still alive" | ts '%Y-%m-%d %H:%M:%S'
sleep 10
fi
done done
echo "Will try to send second kill signal for sure" if pkill -0 -f "clickhouse-server"
kill "$(pgrep -u clickhouse)" 2>/dev/null then
sleep 5 pstree -apgT
echo "clickhouse pids $(pgrep -u clickhouse)" | ts '%Y-%m-%d %H:%M:%S' jobs
echo "Failed to kill the ClickHouse server" | ts '%Y-%m-%d %H:%M:%S'
return 1
fi
} }
start_clickhouse () { start_clickhouse () {
LLVM_PROFILE_FILE='server_%h_%p_%m.profraw' sudo -Eu clickhouse /usr/bin/clickhouse-server --config /etc/clickhouse-server/config.xml & LLVM_PROFILE_FILE='server_%h_%p_%m.profraw' sudo -Eu clickhouse /usr/bin/clickhouse-server --config /etc/clickhouse-server/config.xml &
counter=0
until clickhouse-client --query "SELECT 1"
do
if [ "$counter" -gt 120 ]
then
echo "Cannot start clickhouse-server"
cat /var/log/clickhouse-server/stdout.log
tail -n1000 /var/log/clickhouse-server/stderr.log
tail -n1000 /var/log/clickhouse-server/clickhouse-server.log
break
fi
sleep 0.5
counter=$((counter + 1))
done
} }
chmod 777 / chmod 777 /
@ -44,9 +58,6 @@ chmod 777 -R /var/log/clickhouse-server/
start_clickhouse start_clickhouse
sleep 10
if grep -q -- "--use-skip-list" /usr/bin/clickhouse-test; then if grep -q -- "--use-skip-list" /usr/bin/clickhouse-test; then
SKIP_LIST_OPT="--use-skip-list" SKIP_LIST_OPT="--use-skip-list"
fi fi

View File

@ -2317,4 +2317,10 @@ Possible values:
Default value: `1`. Default value: `1`.
## output_format_tsv_null_representation {#output_format_tsv_null_representation}
Allows configurable `NULL` representation for [TSV](../../interfaces/formats.md#tabseparated) output format. The setting only controls output format and `\N` is the only supported `NULL` representation for TSV input format.
Default value: `\N`.
[Original article](https://clickhouse.tech/docs/en/operations/settings/settings/) <!-- hide --> [Original article](https://clickhouse.tech/docs/en/operations/settings/settings/) <!-- hide -->

View File

@ -0,0 +1,70 @@
# system.replicated_fetches {#system_tables-replicated_fetches}
Contains information about currently running background fetches.
Columns:
- `database` ([String](../../sql-reference/data-types/string.md)) — Name of the database.
- `table` ([String](../../sql-reference/data-types/string.md)) — Name of the table.
- `elapsed` ([Float64](../../sql-reference/data-types/float.md)) — The time elapsed (in seconds) since showing currently running background fetches started.
- `progress` ([Float64](../../sql-reference/data-types/float.md)) — The percentage of completed work from 0 to 1.
- `result_part_name` ([String](../../sql-reference/data-types/string.md)) — The name of the part that will be formed as the result of showing currently running background fetches.
- `result_part_path` ([String](../../sql-reference/data-types/string.md)) — Absolute path to the part that will be formed as the result of showing currently running background fetches.
- `partition_id` ([String](../../sql-reference/data-types/string.md)) — ID of the partition.
- `total_size_bytes_compressed` ([UInt64](../../sql-reference/data-types/int-uint.md)) — The total size (in bytes) of the compressed data in the result part.
- `bytes_read_compressed` ([UInt64](../../sql-reference/data-types/int-uint.md)) — The number of compressed bytes read from the result part.
- `source_replica_path` ([String](../../sql-reference/data-types/string.md)) — Absolute path to the source replica.
- `source_replica_hostname` ([String](../../sql-reference/data-types/string.md)) — Hostname of the source replica.
- `source_replica_port` ([UInt16](../../sql-reference/data-types/int-uint.md)) — Port number of the source replica.
- `interserver_scheme` ([String](../../sql-reference/data-types/string.md)) — Name of the interserver scheme.
- `URI` ([String](../../sql-reference/data-types/string.md)) — Uniform resource identifier.
- `to_detached` ([UInt8](../../sql-reference/data-types/int-uint.md)) — The flag indicates whether the currently running background fetch is being performed using the `TO DETACHED` expression.
- `thread_id` ([UInt64](../../sql-reference/data-types/int-uint.md)) — Thread identifier.
**Example**
``` sql
SELECT * FROM system.replicated_fetches LIMIT 1 FORMAT Vertical;
```
``` text
Row 1:
──────
database: default
table: t
elapsed: 7.243039876
progress: 0.41832135995612835
result_part_name: all_0_0_0
result_part_path: /var/lib/clickhouse/store/700/70080a04-b2de-4adf-9fa5-9ea210e81766/all_0_0_0/
partition_id: all
total_size_bytes_compressed: 1052783726
bytes_read_compressed: 440401920
source_replica_path: /clickhouse/test/t/replicas/1
source_replica_hostname: node1
source_replica_port: 9009
interserver_scheme: http
URI: http://node1:9009/?endpoint=DataPartsExchange%3A%2Fclickhouse%2Ftest%2Ft%2Freplicas%2F1&part=all_0_0_0&client_protocol_version=4&compress=false
to_detached: 0
thread_id: 54
```
**See Also**
- [Managing ReplicatedMergeTree Tables](../../sql-reference/statements/system/#query-language-system-replicated)
[Original article](https://clickhouse.tech/docs/en/operations/system_tables/replicated_fetches) <!--hide-->

View File

@ -1,42 +1,42 @@
# ClickHouse obfuscator # ClickHouse obfuscator
Simple tool for table data obfuscation. A simple tool for table data obfuscation.
It reads input table and produces output table, that retain some properties of input, but contains different data. It reads an input table and produces an output table, that retains some properties of input, but contains different data.
It allows to publish almost real production data for usage in benchmarks. It allows publishing almost real production data for usage in benchmarks.
It is designed to retain the following properties of data: It is designed to retain the following properties of data:
- cardinalities of values (number of distinct values) for every column and for every tuple of columns; - cardinalities of values (number of distinct values) for every column and every tuple of columns;
- conditional cardinalities: number of distinct values of one column under condition on value of another column; - conditional cardinalities: number of distinct values of one column under the condition on the value of another column;
- probability distributions of absolute value of integers; sign of signed integers; exponent and sign for floats; - probability distributions of the absolute value of integers; the sign of signed integers; exponent and sign for floats;
- probability distributions of length of strings; - probability distributions of the length of strings;
- probability of zero values of numbers; empty strings and arrays, NULLs; - probability of zero values of numbers; empty strings and arrays, `NULL`s;
- data compression ratio when compressed with LZ77 and entropy family of codecs;
- continuity (magnitude of difference) of time values across table; continuity of floating point values. - data compression ratio when compressed with LZ77 and entropy family of codecs;
- date component of DateTime values; - continuity (magnitude of difference) of time values across the table; continuity of floating-point values;
- UTF-8 validity of string values; - date component of `DateTime` values;
- string values continue to look somewhat natural.
- UTF-8 validity of string values;
Most of the properties above are viable for performance testing: - string values look natural.
reading data, filtering, aggregation and sorting will work at almost the same speed Most of the properties above are viable for performance testing:
as on original data due to saved cardinalities, magnitudes, compression ratios, etc.
reading data, filtering, aggregatio, and sorting will work at almost the same speed
It works in deterministic fashion: you define a seed value and transform is totally determined by input data and by seed. as on original data due to saved cardinalities, magnitudes, compression ratios, etc.
Some transforms are one to one and could be reversed, so you need to have large enough seed and keep it in secret.
It works in a deterministic fashion: you define a seed value and the transformation is determined by input data and by seed.
It use some cryptographic primitives to transform data, but from the cryptographic point of view, Some transformations are one to one and could be reversed, so you need to have a large seed and keep it in secret.
It doesn't do anything properly and you should never consider the result as secure, unless you have other reasons for it.
It uses some cryptographic primitives to transform data but from the cryptographic point of view, it doesn't do it properly, that is why you should not consider the result as secure unless you have another reason. The result may retain some data you don't want to publish.
It may retain some data you don't want to publish.
It always leave numbers 0, 1, -1 as is. Also it leaves dates, lengths of arrays and null flags exactly as in source data. It always leaves 0, 1, -1 numbers, dates, lengths of arrays, and null flags exactly as in source data.
For example, you have a column IsMobile in your table with values 0 and 1. In transformed data, it will have the same value. For example, you have a column `IsMobile` in your table with values 0 and 1. In transformed data, it will have the same value.
So, the user will be able to count exact ratio of mobile traffic.
So, the user will be able to count the exact ratio of mobile traffic.
Another example, suppose you have some private data in your table, like user email and you don't want to publish any single email address.
If your table is large enough and contain multiple different emails and there is no email that have very high frequency than all others, Let's give another example. When you have some private data in your table, like user email and you don't want to publish any single email address.
It will perfectly anonymize all data. But if you have small amount of different values in a column, it can possibly reproduce some of them. If your table is large enough and contains multiple different emails and no email has a very high frequency than all others, it will anonymize all data. But if you have a small number of different values in a column, it can reproduce some of them.
And you should take care and look at exact algorithm, how this tool works, and probably fine tune some of it command line parameters. You should look at the working algorithm of this tool works, and fine-tune its command line parameters.
This tool works fine only with reasonable amount of data (at least 1000s of rows). This tool works fine only with an average amount of data (at least 1000s of rows).

View File

@ -44,8 +44,6 @@ SELECT sum(y) FROM t_null_big
└────────┘ └────────┘
``` ```
The `sum` function interprets `NULL` as `0`. In particular, this means that if the function receives input of a selection where all the values are `NULL`, then the result will be `0`, not `NULL`.
Now you can use the `groupArray` function to create an array from the `y` column: Now you can use the `groupArray` function to create an array from the `y` column:
``` sql ``` sql

View File

@ -0,0 +1,37 @@
---
toc_priority: 150
---
## initializeAggregation {#initializeaggregation}
Initializes aggregation for your input rows. It is intended for the functions with the suffix `State`.
Use it for tests or to process columns of types `AggregateFunction` and `AggregationgMergeTree`.
**Syntax**
``` sql
initializeAggregation (aggregate_function, column_1, column_2);
```
**Parameters**
- `aggregate_function` — Name of the aggregation function. The state of this function — the creating one. [String](../../../sql-reference/data-types/string.md#string).
- `column_n` — The column to translate it into the function as it's argument. [String](../../../sql-reference/data-types/string.md#string).
**Returned value(s)**
Returns the result of the aggregation for your input rows. The return type will be the same as the return type of function, that `initializeAgregation` takes as first argument.
For example for functions with the suffix `State` the return type will be `AggregateFunction`.
**Example**
Query:
```sql
SELECT uniqMerge(state) FROM (SELECT initializeAggregation('uniqState', number % 3) AS state FROM system.numbers LIMIT 10000);
```
Result:
┌─uniqMerge(state)─┐
│ 3 │
└──────────────────┘

View File

@ -535,18 +535,7 @@ dateDiff('unit', startdate, enddate, [timezone])
- `unit` — Time unit, in which the returned value is expressed. [String](../../sql-reference/syntax.md#syntax-string-literal). - `unit` — Time unit, in which the returned value is expressed. [String](../../sql-reference/syntax.md#syntax-string-literal).
Supported values: Supported values: second, minute, hour, day, week, month, quarter, year.
| unit |
| ---- |
|second |
|minute |
|hour |
|day |
|week |
|month |
|quarter |
|year |
- `startdate` — The first time value to compare. [Date](../../sql-reference/data-types/date.md) or [DateTime](../../sql-reference/data-types/datetime.md). - `startdate` — The first time value to compare. [Date](../../sql-reference/data-types/date.md) or [DateTime](../../sql-reference/data-types/datetime.md).

View File

@ -115,7 +115,21 @@ Returns the “first significant subdomain”. This is a non-standard concept sp
Returns the part of the domain that includes top-level subdomains up to the “first significant subdomain” (see the explanation above). Returns the part of the domain that includes top-level subdomains up to the “first significant subdomain” (see the explanation above).
For example, `cutToFirstSignificantSubdomain('https://news.yandex.com.tr/') = 'yandex.com.tr'`. For example:
- `cutToFirstSignificantSubdomain('https://news.yandex.com.tr/') = 'yandex.com.tr'`.
- `cutToFirstSignificantSubdomain('www.tr') = 'tr'`.
- `cutToFirstSignificantSubdomain('tr') = ''`.
### cutToFirstSignificantSubdomainWithWWW {#cuttofirstsignificantsubdomainwithwww}
Returns the part of the domain that includes top-level subdomains up to the “first significant subdomain”, without stripping "www".
For example:
- `cutToFirstSignificantSubdomain('https://news.yandex.com.tr/') = 'yandex.com.tr'`.
- `cutToFirstSignificantSubdomain('www.tr') = 'www.tr'`.
- `cutToFirstSignificantSubdomain('tr') = ''`.
### port(URL\[, default_port = 0\]) {#port} ### port(URL\[, default_port = 0\]) {#port}

View File

@ -27,9 +27,9 @@ It is applicable when selecting data from tables that use the [MergeTree](../../
### Drawbacks {#drawbacks} ### Drawbacks {#drawbacks}
Queries that use `FINAL` are executed not as fast as similar queries that dont, because: Queries that use `FINAL` are executed slightly slower than similar queries that dont, because:
- Query is executed in a single thread and data is merged during query execution. - Data is merged during query execution.
- Queries with `FINAL` read primary key columns in addition to the columns specified in the query. - Queries with `FINAL` read primary key columns in addition to the columns specified in the query.
**In most cases, avoid using `FINAL`.** The common approach is to use different queries that assume the background processes of the `MergeTree` engine havet happened yet and deal with it by applying aggregation (for example, to discard duplicates). {## TODO: examples ##} **In most cases, avoid using `FINAL`.** The common approach is to use different queries that assume the background processes of the `MergeTree` engine havet happened yet and deal with it by applying aggregation (for example, to discard duplicates). {## TODO: examples ##}

View File

@ -6,7 +6,7 @@ toc_title: GROUP BY
`GROUP BY` clause switches the `SELECT` query into an aggregation mode, which works as follows: `GROUP BY` clause switches the `SELECT` query into an aggregation mode, which works as follows:
- `GROUP BY` clause contains a list of expressions (or a single expression, which is considered to be the list of length one). This list acts as a “grouping key”, while each individual expression will be referred to as a “key expressions”. - `GROUP BY` clause contains a list of expressions (or a single expression, which is considered to be the list of length one). This list acts as a “grouping key”, while each individual expression will be referred to as a “key expression”.
- All the expressions in the [SELECT](../../../sql-reference/statements/select/index.md), [HAVING](../../../sql-reference/statements/select/having.md), and [ORDER BY](../../../sql-reference/statements/select/order-by.md) clauses **must** be calculated based on key expressions **or** on [aggregate functions](../../../sql-reference/aggregate-functions/index.md) over non-key expressions (including plain columns). In other words, each column selected from the table must be used either in a key expression or inside an aggregate function, but not both. - All the expressions in the [SELECT](../../../sql-reference/statements/select/index.md), [HAVING](../../../sql-reference/statements/select/having.md), and [ORDER BY](../../../sql-reference/statements/select/order-by.md) clauses **must** be calculated based on key expressions **or** on [aggregate functions](../../../sql-reference/aggregate-functions/index.md) over non-key expressions (including plain columns). In other words, each column selected from the table must be used either in a key expression or inside an aggregate function, but not both.
- Result of aggregating `SELECT` query will contain as many rows as there were unique values of “grouping key” in source table. Usually this signficantly reduces the row count, often by orders of magnitude, but not necessarily: row count stays the same if all “grouping key” values were distinct. - Result of aggregating `SELECT` query will contain as many rows as there were unique values of “grouping key” in source table. Usually this signficantly reduces the row count, often by orders of magnitude, but not necessarily: row count stays the same if all “grouping key” values were distinct.
@ -45,6 +45,154 @@ You can see that `GROUP BY` for `y = NULL` summed up `x`, as if `NULL` is this v
If you pass several keys to `GROUP BY`, the result will give you all the combinations of the selection, as if `NULL` were a specific value. If you pass several keys to `GROUP BY`, the result will give you all the combinations of the selection, as if `NULL` were a specific value.
## WITH ROLLUP Modifier {#with-rollup-modifier}
`WITH ROLLUP` modifier is used to calculate subtotals for the key expressions, based on their order in the `GROUP BY` list. The subtotals rows are added after the result table.
The subtotals are calculated in the reverse order: at first subtotals are calculated for the last key expression in the list, then for the previous one, and so on up to the first key expression.
In the subtotals rows the values of already "grouped" key expressions are set to `0` or empty line.
!!! note "Note"
Mind that [HAVING](../../../sql-reference/statements/select/having.md) clause can affect the subtotals results.
**Example**
Consider the table t:
```text
┌─year─┬─month─┬─day─┐
│ 2019 │ 1 │ 5 │
│ 2019 │ 1 │ 15 │
│ 2020 │ 1 │ 5 │
│ 2020 │ 1 │ 15 │
│ 2020 │ 10 │ 5 │
│ 2020 │ 10 │ 15 │
└──────┴───────┴─────┘
```
Query:
```sql
SELECT year, month, day, count(*) FROM t GROUP BY year, month, day WITH ROLLUP;
```
As `GROUP BY` section has three key expressions, the result contains four tables with subtotals "rolled up" from right to left:
- `GROUP BY year, month, day`;
- `GROUP BY year, month` (and `day` column is filled with zeros);
- `GROUP BY year` (now `month, day` columns are both filled with zeros);
- and totals (and all three key expression columns are zeros).
```text
┌─year─┬─month─┬─day─┬─count()─┐
│ 2020 │ 10 │ 15 │ 1 │
│ 2020 │ 1 │ 5 │ 1 │
│ 2019 │ 1 │ 5 │ 1 │
│ 2020 │ 1 │ 15 │ 1 │
│ 2019 │ 1 │ 15 │ 1 │
│ 2020 │ 10 │ 5 │ 1 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 1 │ 0 │ 2 │
│ 2020 │ 1 │ 0 │ 2 │
│ 2020 │ 10 │ 0 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 0 │ 0 │ 2 │
│ 2020 │ 0 │ 0 │ 4 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 0 │ 0 │ 6 │
└──────┴───────┴─────┴─────────┘
```
## WITH CUBE Modifier {#with-cube-modifier}
`WITH CUBE` modifier is used to calculate subtotals for every combination of the key expressions in the `GROUP BY` list. The subtotals rows are added after the result table.
In the subtotals rows the values of all "grouped" key expressions are set to `0` or empty line.
!!! note "Note"
Mind that [HAVING](../../../sql-reference/statements/select/having.md) clause can affect the subtotals results.
**Example**
Consider the table t:
```text
┌─year─┬─month─┬─day─┐
│ 2019 │ 1 │ 5 │
│ 2019 │ 1 │ 15 │
│ 2020 │ 1 │ 5 │
│ 2020 │ 1 │ 15 │
│ 2020 │ 10 │ 5 │
│ 2020 │ 10 │ 15 │
└──────┴───────┴─────┘
```
Query:
```sql
SELECT year, month, day, count(*) FROM t GROUP BY year, month, day WITH CUBE;
```
As `GROUP BY` section has three key expressions, the result contains eight tables with subtotals for all key expression combinations:
- `GROUP BY year, month, day`
- `GROUP BY year, month`
- `GROUP BY year, day`
- `GROUP BY year`
- `GROUP BY month, day`
- `GROUP BY month`
- `GROUP BY day`
- and totals.
Columns, excluded from `GROUP BY`, are filled with zeros.
```text
┌─year─┬─month─┬─day─┬─count()─┐
│ 2020 │ 10 │ 15 │ 1 │
│ 2020 │ 1 │ 5 │ 1 │
│ 2019 │ 1 │ 5 │ 1 │
│ 2020 │ 1 │ 15 │ 1 │
│ 2019 │ 1 │ 15 │ 1 │
│ 2020 │ 10 │ 5 │ 1 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 1 │ 0 │ 2 │
│ 2020 │ 1 │ 0 │ 2 │
│ 2020 │ 10 │ 0 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2020 │ 0 │ 5 │ 2 │
│ 2019 │ 0 │ 5 │ 1 │
│ 2020 │ 0 │ 15 │ 2 │
│ 2019 │ 0 │ 15 │ 1 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 0 │ 0 │ 2 │
│ 2020 │ 0 │ 0 │ 4 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 1 │ 5 │ 2 │
│ 0 │ 10 │ 15 │ 1 │
│ 0 │ 10 │ 5 │ 1 │
│ 0 │ 1 │ 15 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 1 │ 0 │ 4 │
│ 0 │ 10 │ 0 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 0 │ 5 │ 3 │
│ 0 │ 0 │ 15 │ 3 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 0 │ 0 │ 6 │
└──────┴───────┴─────┴─────────┘
```
## WITH TOTALS Modifier {#with-totals-modifier} ## WITH TOTALS Modifier {#with-totals-modifier}
If the `WITH TOTALS` modifier is specified, another row will be calculated. This row will have key columns containing default values (zeros or empty lines), and columns of aggregate functions with the values calculated across all the rows (the “total” values). If the `WITH TOTALS` modifier is specified, another row will be calculated. This row will have key columns containing default values (zeros or empty lines), and columns of aggregate functions with the values calculated across all the rows (the “total” values).
@ -88,8 +236,6 @@ SELECT
FROM hits FROM hits
``` ```
However, in contrast to standard SQL, if the table doesnt have any rows (either there arent any at all, or there arent any after using WHERE to filter), an empty result is returned, and not the result from one of the rows containing the initial values of aggregate functions.
As opposed to MySQL (and conforming to standard SQL), you cant get some value of some column that is not in a key or aggregate function (except constant expressions). To work around this, you can use the any aggregate function (get the first encountered value) or min/max. As opposed to MySQL (and conforming to standard SQL), you cant get some value of some column that is not in a key or aggregate function (except constant expressions). To work around this, you can use the any aggregate function (get the first encountered value) or min/max.
Example: Example:
@ -105,10 +251,6 @@ GROUP BY domain
For every different key value encountered, `GROUP BY` calculates a set of aggregate function values. For every different key value encountered, `GROUP BY` calculates a set of aggregate function values.
`GROUP BY` is not supported for array columns.
A constant cant be specified as arguments for aggregate functions. Example: `sum(1)`. Instead of this, you can get rid of the constant. Example: `count()`.
## Implementation Details {#implementation-details} ## Implementation Details {#implementation-details}
Aggregation is one of the most important features of a column-oriented DBMS, and thus its implementation is one of the most heavily optimized parts of ClickHouse. By default, aggregation is done in memory using a hash-table. It has 40+ specializations that are chosen automatically depending on “grouping key” data types. Aggregation is one of the most important features of a column-oriented DBMS, and thus its implementation is one of the most heavily optimized parts of ClickHouse. By default, aggregation is done in memory using a hash-table. It has 40+ specializations that are chosen automatically depending on “grouping key” data types.

View File

@ -20,7 +20,7 @@ SELECT [DISTINCT] expr_list
[GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>) [GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>)
[PREWHERE expr] [PREWHERE expr]
[WHERE expr] [WHERE expr]
[GROUP BY expr_list] [WITH TOTALS] [GROUP BY expr_list] [WITH ROLLUP|WITH CUBE] [WITH TOTALS]
[HAVING expr] [HAVING expr]
[ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr]
[LIMIT [offset_value, ]n BY columns] [LIMIT [offset_value, ]n BY columns]
@ -159,4 +159,111 @@ If the query omits the `DISTINCT`, `GROUP BY` and `ORDER BY` clauses and the `IN
For more information, see the section “Settings”. It is possible to use external sorting (saving temporary tables to a disk) and external aggregation. For more information, see the section “Settings”. It is possible to use external sorting (saving temporary tables to a disk) and external aggregation.
{## [Original article](https://clickhouse.tech/docs/en/sql-reference/statements/select/) ##} ## SELECT modifiers {#select-modifiers}
You can use the following modifiers in `SELECT` queries.
### APPLY {#apply-modifier}
Allows you to invoke some function for each row returned by an outer table expression of a query.
**Syntax:**
``` sql
SELECT <expr> APPLY( <func> ) FROM [db.]table_name
```
**Example:**
``` sql
CREATE TABLE columns_transformers (i Int64, j Int16, k Int64) ENGINE = MergeTree ORDER by (i);
INSERT INTO columns_transformers VALUES (100, 10, 324), (120, 8, 23);
SELECT * APPLY(sum) FROM columns_transformers;
```
```
┌─sum(i)─┬─sum(j)─┬─sum(k)─┐
│ 220 │ 18 │ 347 │
└────────┴────────┴────────┘
```
### EXCEPT {#except-modifier}
Specifies the names of one or more columns to exclude from the result. All matching column names are omitted from the output.
**Syntax:**
``` sql
SELECT <expr> EXCEPT ( col_name1 [, col_name2, col_name3, ...] ) FROM [db.]table_name
```
**Example:**
``` sql
SELECT * EXCEPT (i) from columns_transformers;
```
```
┌──j─┬───k─┐
│ 10 │ 324 │
│ 8 │ 23 │
└────┴─────┘
```
### REPLACE {#replace-modifier}
Specifies one or more [expression aliases](../../../sql-reference/syntax.md#syntax-expression_aliases). Each alias must match a column name from the `SELECT *` statement. In the output column list, the column that matches the alias is replaced by the expression in that `REPLACE`.
This modifier does not change the names or order of columns. However, it can change the value and the value type.
**Syntax:**
``` sql
SELECT <expr> REPLACE( <expr> AS col_name) from [db.]table_name
```
**Example:**
``` sql
SELECT * REPLACE(i + 1 AS i) from columns_transformers;
```
```
┌───i─┬──j─┬───k─┐
│ 101 │ 10 │ 324 │
│ 121 │ 8 │ 23 │
└─────┴────┴─────┘
```
### Modifier Combinations {#modifier-combinations}
You can use each modifier separately or combine them.
**Examples:**
Using the same modifier multiple times.
``` sql
SELECT COLUMNS('[jk]') APPLY(toString) APPLY(length) APPLY(max) from columns_transformers;
```
```
┌─max(length(toString(j)))─┬─max(length(toString(k)))─┐
│ 2 │ 3 │
└──────────────────────────┴──────────────────────────┘
```
Using multiple modifiers in a single query.
``` sql
SELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from columns_transformers;
```
```
┌─sum(plus(i, 1))─┬─sum(k)─┐
│ 222 │ 347 │
└─────────────────┴────────┘
```
[Original article](https://clickhouse.tech/docs/en/sql-reference/statements/select/)
<!--hide-->

View File

@ -2187,4 +2187,10 @@ SELECT CAST(toNullable(toInt32(0)) AS Int32) as x, toTypeName(x);
Значение по умолчанию: `1`. Значение по умолчанию: `1`.
## output_format_tsv_null_representation {#output_format_tsv_null_representation}
Позволяет настраивать представление `NULL` для формата выходных данных [TSV](../../interfaces/formats.md#tabseparated). Настройка управляет форматом выходных данных, `\N` является единственным поддерживаемым представлением для формата входных данных TSV.
Значение по умолчанию: `\N`.
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/settings/settings/) <!--hide--> [Оригинальная статья](https://clickhouse.tech/docs/ru/operations/settings/settings/) <!--hide-->

View File

@ -0,0 +1,70 @@
# system.replicated_fetches {#system_tables-replicated_fetches}
Содержит информацию о выполняемых в данный момент фоновых операциях скачивания кусков данных с других реплик.
Столбцы:
- `database` ([String](../../sql-reference/data-types/string.md)) — имя базы данных.
- `table` ([String](../../sql-reference/data-types/string.md)) — имя таблицы.
- `elapsed` ([Float64](../../sql-reference/data-types/float.md)) — время, прошедшее от момента начала скачивания куска, в секундах.
- `progress` ([Float64](../../sql-reference/data-types/float.md)) — доля выполненной работы от 0 до 1.
- `result_part_name` ([String](../../sql-reference/data-types/string.md)) — имя скачиваемого куска.
- `result_part_path` ([String](../../sql-reference/data-types/string.md)) — абсолютный путь к скачиваемому куску.
- `partition_id` ([String](../../sql-reference/data-types/string.md)) — идентификатор партиции.
- `total_size_bytes_compressed` ([UInt64](../../sql-reference/data-types/int-uint.md)) — общий размер сжатой информации в скачиваемом куске в байтах.
- `bytes_read_compressed` ([UInt64](../../sql-reference/data-types/int-uint.md)) — размер сжатой информации, считанной из скачиваемого куска, в байтах.
- `source_replica_path` ([String](../../sql-reference/data-types/string.md)) — абсолютный путь к исходной реплике.
- `source_replica_hostname` ([String](../../sql-reference/data-types/string.md)) — имя хоста исходной реплики.
- `source_replica_port` ([UInt16](../../sql-reference/data-types/int-uint.md)) — номер порта исходной реплики.
- `interserver_scheme` ([String](../../sql-reference/data-types/string.md)) — имя межсерверной схемы.
- `URI` ([String](../../sql-reference/data-types/string.md)) — универсальный идентификатор ресурса.
- `to_detached` ([UInt8](../../sql-reference/data-types/int-uint.md)) — флаг, указывающий на использование выражения `TO DETACHED` в текущих фоновых операциях.
- `thread_id` ([UInt64](../../sql-reference/data-types/int-uint.md)) — идентификатор потока.
**Пример**
``` sql
SELECT * FROM system.replicated_fetches LIMIT 1 FORMAT Vertical;
```
``` text
Row 1:
──────
database: default
table: t
elapsed: 7.243039876
progress: 0.41832135995612835
result_part_name: all_0_0_0
result_part_path: /var/lib/clickhouse/store/700/70080a04-b2de-4adf-9fa5-9ea210e81766/all_0_0_0/
partition_id: all
total_size_bytes_compressed: 1052783726
bytes_read_compressed: 440401920
source_replica_path: /clickhouse/test/t/replicas/1
source_replica_hostname: node1
source_replica_port: 9009
interserver_scheme: http
URI: http://node1:9009/?endpoint=DataPartsExchange%3A%2Fclickhouse%2Ftest%2Ft%2Freplicas%2F1&part=all_0_0_0&client_protocol_version=4&compress=false
to_detached: 0
thread_id: 54
```
**Смотрите также**
- [Управление таблицами ReplicatedMergeTree](../../sql-reference/statements/system/#query-language-system-replicated)
[Оригинальная статья](https://clickhouse.tech/docs/en/operations/system_tables/replicated_fetches) <!--hide-->

View File

@ -0,0 +1,43 @@
# Обфускатор ClickHouse
Простой инструмент для обфускации табличных данных.
Он считывает данные входной таблицы и создает выходную таблицу, которая сохраняет некоторые свойства входных данных, но при этом содержит другие данные.
Это позволяет публиковать практически реальные данные и использовать их в тестах на производительность.
Обфускатор предназначен для сохранения следующих свойств данных:
- кардинальность (количество уникальных данных) для каждого столбца и каждого кортежа столбцов;
- условная кардинальность: количество уникальных данных одного столбца в соответствии со значением другого столбца;
- вероятностные распределения абсолютного значения целых чисел; знак числа типа Int; показатель степени и знак для чисел с плавающей запятой;
- вероятностное распределение длины строк;
- вероятность нулевых значений чисел; пустые строки и массивы, `NULL`;
- степень сжатия данных алгоритмом LZ77 и семейством энтропийных кодеков;
- непрерывность (величина разницы) значений времени в таблице; непрерывность значений с плавающей запятой;
- дату из значений `DateTime`;
- кодировка UTF-8 значений строки;
- строковые значения выглядят естественным образом.
Большинство перечисленных выше свойств пригодны для тестирования производительности. Чтение данных, фильтрация, агрегирование и сортировка будут работать почти с той же скоростью, что и исходные данные, благодаря сохраненной кардинальности, величине, степени сжатия и т. д.
Он работает детерминированно. Вы задаёте значение инициализатора, а преобразование полностью определяется входными данными и инициализатором.
Некоторые преобразования выполняются один к одному, и их можно отменить. Поэтому нужно использовать большое значение инициализатора и хранить его в секрете.
Обфускатор использует некоторые криптографические примитивы для преобразования данных, но, с криптографической точки зрения, результат будет небезопасным. В нем могут сохраниться данные, которые не следует публиковать.
Он всегда оставляет без изменений числа 0, 1, -1, даты, длины массивов и нулевые флаги.
Например, если у вас есть столбец `IsMobile` в таблице со значениями 0 и 1, то в преобразованных данных он будет иметь то же значение.
Таким образом, пользователь сможет посчитать точное соотношение мобильного трафика.
Давайте рассмотрим случай, когда у вас есть какие-то личные данные в таблице (например, электронная почта пользователя), и вы не хотите их публиковать.
Если ваша таблица достаточно большая и содержит несколько разных электронных почтовых адресов, и ни один из них не встречается часто, то обфускатор полностью анонимизирует все данные. Но, если у вас есть небольшое количество разных значений в столбце, он может скопировать некоторые из них.
В этом случае вам следует посмотреть на алгоритм работы инструмента и настроить параметры командной строки.
Обфускатор полезен в работе со средним объемом данных (не менее 1000 строк).

View File

@ -44,8 +44,6 @@ SELECT sum(y) FROM t_null_big
└────────┘ └────────┘
``` ```
Функция `sum` работает с `NULL` как с `0`. В частности, это означает, что если на вход в функцию подать выборку, где все значения `NULL`, то результат будет `0`, а не `NULL`.
Теперь с помощью функции `groupArray` сформируем массив из столбца `y`: Теперь с помощью функции `groupArray` сформируем массив из столбца `y`:
``` sql ``` sql

View File

@ -0,0 +1,40 @@
---
toc_priority: 150
---
## initializeAggregation {#initializeaggregation}
Инициализирует агрегацию для введеных строчек. Предназначена для функций с суффиксом `State`.
Поможет вам проводить тесты или работать со столбцами типов: `AggregateFunction` и `AggregationgMergeTree`.
**Синтаксис**
``` sql
initializeAggregation (aggregate_function, column_1, column_2);
```
**Параметры**
- `aggregate_function` — название функции агрегации, состояние которой нужно создать. [String](../../../sql-reference/data-types/string.md#string).
- `column_n` — столбец, который передается в функцию агрегации как аргумент. [String](../../../sql-reference/data-types/string.md#string).
**Возвращаемое значение**
Возвращает результат агрегации введенной информации. Тип возвращаемого значения такой же, как и для функции, которая становится первым аргументом для `initializeAgregation`.
Пример:
Возвращаемый тип функций с суффиксом `State``AggregateFunction`.
**Пример**
Запрос:
```sql
SELECT uniqMerge(state) FROM (SELECT initializeAggregation('uniqState', number % 3) AS state FROM system.numbers LIMIT 10000);
```
Результат:
┌─uniqMerge(state)─┐
│ 3 │
└──────────────────┘

View File

@ -27,9 +27,9 @@ toc_title: FROM
### Недостатки {#drawbacks} ### Недостатки {#drawbacks}
Запросы, которые используют `FINAL` выполняются не так быстро, как аналогичные запросы без него, потому что: Запросы, которые используют `FINAL` выполняются немного медленее, чем аналогичные запросы без него, потому что:
- Запрос выполняется в одном потоке, и данные мёржатся во время выполнения запроса. - Данные мёржатся во время выполнения запроса.
- Запросы с модификатором `FINAL` читают столбцы первичного ключа в дополнение к столбцам, используемым в запросе. - Запросы с модификатором `FINAL` читают столбцы первичного ключа в дополнение к столбцам, используемым в запросе.
**В большинстве случаев избегайте использования `FINAL`.** Общий подход заключается в использовании агрегирующих запросов, которые предполагают, что фоновые процессы движков семейства `MergeTree` ещё не случились (например, сами отбрасывают дубликаты). {## TODO: examples ##} **В большинстве случаев избегайте использования `FINAL`.** Общий подход заключается в использовании агрегирующих запросов, которые предполагают, что фоновые процессы движков семейства `MergeTree` ещё не случились (например, сами отбрасывают дубликаты). {## TODO: examples ##}

View File

@ -43,6 +43,153 @@ toc_title: GROUP BY
Если в `GROUP BY` передать несколько ключей, то в результате мы получим все комбинации выборки, как если бы `NULL` был конкретным значением. Если в `GROUP BY` передать несколько ключей, то в результате мы получим все комбинации выборки, как если бы `NULL` был конкретным значением.
## Модификатор WITH ROLLUP {#with-rollup-modifier}
Модификатор `WITH ROLLUP` применяется для подсчета подытогов для ключевых выражений. При этом учитывается порядок следования ключевых выражений в списке `GROUP BY`. Подытоги подсчитываются в обратном порядке: сначала для последнего ключевого выражения в списке, потом для предпоследнего и так далее вплоть до самого первого ключевого выражения.
Строки с подытогами добавляются в конец результирующей таблицы. В колонках, по которым строки уже сгруппированы, указывается значение `0` или пустая строка.
!!! note "Примечание"
Если в запросе есть секция [HAVING](../../../sql-reference/statements/select/having.md), она может повлиять на результаты расчета подытогов.
**Пример**
Рассмотрим таблицу t:
```text
┌─year─┬─month─┬─day─┐
│ 2019 │ 1 │ 5 │
│ 2019 │ 1 │ 15 │
│ 2020 │ 1 │ 5 │
│ 2020 │ 1 │ 15 │
│ 2020 │ 10 │ 5 │
│ 2020 │ 10 │ 15 │
└──────┴───────┴─────┘
```
Запрос:
```sql
SELECT year, month, day, count(*) FROM t GROUP BY year, month, day WITH ROLLUP;
```
Поскольку секция `GROUP BY` содержит три ключевых выражения, результат состоит из четырех таблиц с подытогами, которые как бы "сворачиваются" справа налево:
- `GROUP BY year, month, day`;
- `GROUP BY year, month` (а колонка `day` заполнена нулями);
- `GROUP BY year` (теперь обе колонки `month, day` заполнены нулями);
- и общий итог (все три колонки с ключевыми выражениями заполнены нулями).
```text
┌─year─┬─month─┬─day─┬─count()─┐
│ 2020 │ 10 │ 15 │ 1 │
│ 2020 │ 1 │ 5 │ 1 │
│ 2019 │ 1 │ 5 │ 1 │
│ 2020 │ 1 │ 15 │ 1 │
│ 2019 │ 1 │ 15 │ 1 │
│ 2020 │ 10 │ 5 │ 1 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 1 │ 0 │ 2 │
│ 2020 │ 1 │ 0 │ 2 │
│ 2020 │ 10 │ 0 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 0 │ 0 │ 2 │
│ 2020 │ 0 │ 0 │ 4 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 0 │ 0 │ 6 │
└──────┴───────┴─────┴─────────┘
```
## Модификатор WITH CUBE {#with-cube-modifier}
Модификатор `WITH CUBE` применятеся для расчета подытогов по всем комбинациям группировки ключевых выражений в списке `GROUP BY`.
Строки с подытогами добавляются в конец результирующей таблицы. В колонках, по которым выполняется группировка, указывается значение `0` или пустая строка.
!!! note "Примечание"
Если в запросе есть секция [HAVING](../../../sql-reference/statements/select/having.md), она может повлиять на результаты расчета подытогов.
**Пример**
Рассмотрим таблицу t:
```text
┌─year─┬─month─┬─day─┐
│ 2019 │ 1 │ 5 │
│ 2019 │ 1 │ 15 │
│ 2020 │ 1 │ 5 │
│ 2020 │ 1 │ 15 │
│ 2020 │ 10 │ 5 │
│ 2020 │ 10 │ 15 │
└──────┴───────┴─────┘
```
Query:
```sql
SELECT year, month, day, count(*) FROM t GROUP BY year, month, day WITH CUBE;
```
Поскольку секция `GROUP BY` содержит три ключевых выражения, результат состоит из восьми таблиц с подытогами — по таблице для каждой комбинации ключевых выражений:
- `GROUP BY year, month, day`
- `GROUP BY year, month`
- `GROUP BY year, day`
- `GROUP BY year`
- `GROUP BY month, day`
- `GROUP BY month`
- `GROUP BY day`
- и общий итог.
Колонки, которые не участвуют в `GROUP BY`, заполнены нулями.
```text
┌─year─┬─month─┬─day─┬─count()─┐
│ 2020 │ 10 │ 15 │ 1 │
│ 2020 │ 1 │ 5 │ 1 │
│ 2019 │ 1 │ 5 │ 1 │
│ 2020 │ 1 │ 15 │ 1 │
│ 2019 │ 1 │ 15 │ 1 │
│ 2020 │ 10 │ 5 │ 1 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 1 │ 0 │ 2 │
│ 2020 │ 1 │ 0 │ 2 │
│ 2020 │ 10 │ 0 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2020 │ 0 │ 5 │ 2 │
│ 2019 │ 0 │ 5 │ 1 │
│ 2020 │ 0 │ 15 │ 2 │
│ 2019 │ 0 │ 15 │ 1 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 2019 │ 0 │ 0 │ 2 │
│ 2020 │ 0 │ 0 │ 4 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 1 │ 5 │ 2 │
│ 0 │ 10 │ 15 │ 1 │
│ 0 │ 10 │ 5 │ 1 │
│ 0 │ 1 │ 15 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 1 │ 0 │ 4 │
│ 0 │ 10 │ 0 │ 2 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 0 │ 5 │ 3 │
│ 0 │ 0 │ 15 │ 3 │
└──────┴───────┴─────┴─────────┘
┌─year─┬─month─┬─day─┬─count()─┐
│ 0 │ 0 │ 0 │ 6 │
└──────┴───────┴─────┴─────────┘
```
## Модификатор WITH TOTALS {#with-totals-modifier} ## Модификатор WITH TOTALS {#with-totals-modifier}
Если указан модификатор `WITH TOTALS`, то будет посчитана ещё одна строчка, в которой в столбцах-ключах будут содержаться значения по умолчанию (нули, пустые строки), а в столбцах агрегатных функций - значения, посчитанные по всем строкам («тотальные» значения). Если указан модификатор `WITH TOTALS`, то будет посчитана ещё одна строчка, в которой в столбцах-ключах будут содержаться значения по умолчанию (нули, пустые строки), а в столбцах агрегатных функций - значения, посчитанные по всем строкам («тотальные» значения).
@ -86,8 +233,6 @@ SELECT
FROM hits FROM hits
``` ```
Но, в отличие от стандартного SQL, если в таблице нет строк (вообще нет или после фильтрации с помощью WHERE), в качестве результата возвращается пустой результат, а не результат из одной строки, содержащий «начальные» значения агрегатных функций.
В отличие от MySQL (и в соответствии со стандартом SQL), вы не можете получить какое-нибудь значение некоторого столбца, не входящего в ключ или агрегатную функцию (за исключением константных выражений). Для обхода этого вы можете воспользоваться агрегатной функцией any (получить первое попавшееся значение) или min/max. В отличие от MySQL (и в соответствии со стандартом SQL), вы не можете получить какое-нибудь значение некоторого столбца, не входящего в ключ или агрегатную функцию (за исключением константных выражений). Для обхода этого вы можете воспользоваться агрегатной функцией any (получить первое попавшееся значение) или min/max.
Пример: Пример:
@ -103,10 +248,6 @@ GROUP BY domain
GROUP BY вычисляет для каждого встретившегося различного значения ключей, набор значений агрегатных функций. GROUP BY вычисляет для каждого встретившегося различного значения ключей, набор значений агрегатных функций.
Не поддерживается GROUP BY по столбцам-массивам.
Не поддерживается указание констант в качестве аргументов агрегатных функций. Пример: `sum(1)`. Вместо этого, вы можете избавиться от констант. Пример: `count()`.
## Детали реализации {#implementation-details} ## Детали реализации {#implementation-details}
Агрегация является одной из наиболее важных возможностей столбцовых СУБД, и поэтому её реализация является одной из наиболее сильно оптимизированных частей ClickHouse. По умолчанию агрегирование выполняется в памяти с помощью хэш-таблицы. Она имеет более 40 специализаций, которые выбираются автоматически в зависимости от типов данных ключа группировки. Агрегация является одной из наиболее важных возможностей столбцовых СУБД, и поэтому её реализация является одной из наиболее сильно оптимизированных частей ClickHouse. По умолчанию агрегирование выполняется в памяти с помощью хэш-таблицы. Она имеет более 40 специализаций, которые выбираются автоматически в зависимости от типов данных ключа группировки.

View File

@ -18,7 +18,7 @@ SELECT [DISTINCT] expr_list
[GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>) [GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>)
[PREWHERE expr] [PREWHERE expr]
[WHERE expr] [WHERE expr]
[GROUP BY expr_list] [WITH TOTALS] [GROUP BY expr_list] [WITH ROLLUP|WITH CUBE] [WITH TOTALS]
[HAVING expr] [HAVING expr]
[ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr]
[LIMIT [offset_value, ]n BY columns] [LIMIT [offset_value, ]n BY columns]

View File

@ -21,15 +21,15 @@ toc_title: "\u266A\u64CD\u573A\u266A"
ClickHouse体验还有如下 ClickHouse体验还有如下
[ClickHouse管理服务](https://cloud.yandex.com/services/managed-clickhouse) [ClickHouse管理服务](https://cloud.yandex.com/services/managed-clickhouse)
实例托管 [Yandex云](https://cloud.yandex.com/). 实例托管 [Yandex云](https://cloud.yandex.com/)
更多信息 [云提供商](../commercial/cloud.md). 更多信息 [云提供商](../commercial/cloud.md)
ClickHouse体验平台界面实际上是通过ClickHouse [HTTP API](../interfaces/http.md)接口实现的. ClickHouse体验平台界面实际上是通过ClickHouse [HTTP API](../interfaces/http.md)接口实现的.
体验平台后端只是一个ClickHouse集群没有任何额外的服务器端应用程序。 体验平台后端只是一个ClickHouse集群没有任何额外的服务器端应用程序。
体验平台也同样提供了ClickHouse HTTPS服务端口。 体验平台也同样提供了ClickHouse HTTPS服务端口。
您可以使用任何HTTP客户端向体验平台进行查询例如 [curl](https://curl.haxx.se) 或 [wget](https://www.gnu.org/software/wget/),或使用以下方式建立连接 [JDBC](../interfaces/jdbc.md) 或 [ODBC](../interfaces/odbc.md) 司机 您可以使用任何HTTP客户端向体验平台进行查询例如 [curl](https://curl.haxx.se) 或 [wget](https://www.gnu.org/software/wget/),或使用以下方式建立连接 [JDBC](../interfaces/jdbc.md) 或 [ODBC](../interfaces/odbc.md) 驱动。
有关支持ClickHouse的软件产品的更多信息请访问 [这里](../interfaces/index.md). 有关支持ClickHouse的软件产品的更多信息请访问 [这里](../interfaces/index.md)
| 参数 | 值 | | 参数 | 值 |
|:---------|:--------------------------------------| |:---------|:--------------------------------------|

View File

@ -33,10 +33,10 @@ ClickHouse 收集的指标项:
- 服务用于计算的资源占用的各种指标。 - 服务用于计算的资源占用的各种指标。
- 关于查询处理的常见统计信息。 - 关于查询处理的常见统计信息。
可以在 [系统指标](system-tables/metrics.md#system_tables-metrics) [系统事件](system-tables/events.md#system_tables-events) 以及[系统异步指标](system-tables/asynchronous_metrics.md#system_tables-asynchronous_metrics) 等系统表查看所有的指标项。 可以在[系统指标](system-tables/metrics.md#system_tables-metrics)[系统事件](system-tables/events.md#system_tables-events)以及[系统异步指标](system-tables/asynchronous_metrics.md#system_tables-asynchronous_metrics)等系统表查看所有的指标项。
可以配置ClickHouse 往 [石墨](https://github.com/graphite-project)导入指标。 参考 [石墨部分](server-configuration-parameters/settings.md#server_configuration_parameters-graphite) 配置文件。在配置指标导出之前需要参考Graphite[官方教程](https://graphite.readthedocs.io/en/latest/install.html)搭建服务。 可以配置ClickHouse向[Graphite](https://github.com/graphite-project)推送监控信息并导入指标。参考[Graphite监控](server-configuration-parameters/settings.md#server_configuration_parameters-graphite)配置文件。在配置指标导出之前,需要参考[Graphite官方教程](https://graphite.readthedocs.io/en/latest/install.html)搭建Graphite服务。
此外您可以通过HTTP API监视服务器可用性。 将HTTP GET请求发送到 `/ping` 如果服务器可用,它将以 `200 OK` 响应。 此外您可以通过HTTP API监视服务器可用性。将HTTP GET请求发送到`/ping`。如果服务器可用,它将以 `200 OK` 响应。
要监视服务器集群的配置,应设置[max_replica_delay_for_distributed_queries](settings/settings.md#settings-max_replica_delay_for_distributed_queries)参数并使用HTTP资源`/replicas_status`。 如果副本可用,并且不延迟在其他副本之后,则对`/replicas_status`的请求将返回200 OK。 如果副本滞后,请求将返回 `503 HTTP_SERVICE_UNAVAILABLE`,包括有关待办事项大小的信息。 要监视服务器集群的配置,应设置[max_replica_delay_for_distributed_queries](settings/settings.md#settings-max_replica_delay_for_distributed_queries)参数并使用HTTP资源`/replicas_status`。 如果副本可用,并且不延迟在其他副本之后,则对`/replicas_status`的请求将返回`200 OK`。 如果副本滞后,请求将返回`503 HTTP_SERVICE_UNAVAILABLE`,包括有关待办事项大小的信息。

View File

@ -6,7 +6,7 @@
我们使用RoaringBitmap实际存储位图对象当基数小于或等于32时它使用Set保存。当基数大于32时它使用RoaringBitmap保存。这也是为什么低基数集的存储更快的原因。 我们使用RoaringBitmap实际存储位图对象当基数小于或等于32时它使用Set保存。当基数大于32时它使用RoaringBitmap保存。这也是为什么低基数集的存储更快的原因。
有关RoaringBitmap的更多信息请参阅[呻吟声](https://github.com/RoaringBitmap/CRoaring)。 有关RoaringBitmap的更多信息请参阅[RoaringBitmap](https://github.com/RoaringBitmap/CRoaring)。
## bitmapBuild {#bitmapbuild} ## bitmapBuild {#bitmapbuild}

View File

@ -0,0 +1 @@
../../../tests/config/config.d/logging_no_rotate.xml

View File

@ -11,6 +11,9 @@
<level>trace</level> <level>trace</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log> <log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog> <errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<!-- Rotation policy
See https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/FileChannel.h#L54-L85
-->
<size>1000M</size> <size>1000M</size>
<count>10</count> <count>10</count>
<!-- <console>1</console> --> <!-- Default behavior is autodetection (log to console if not daemon mode and is tty) --> <!-- <console>1</console> --> <!-- Default behavior is autodetection (log to console if not daemon mode and is tty) -->

View File

@ -1,6 +1,7 @@
<html> <!-- TODO If I write DOCTYPE HTML something changes but I don't know what. --> <html> <!-- TODO If I write DOCTYPE HTML something changes but I don't know what. -->
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NCIgaGVpZ2h0PSI0OCIgdmlld0JveD0iMCAwIDkgOCI+PHN0eWxlPi5ve2ZpbGw6I2ZjMH0ucntmaWxsOnJlZH08L3N0eWxlPjxwYXRoIGQ9Ik0wLDcgaDEgdjEgaC0xIHoiIGNsYXNzPSJyIi8+PHBhdGggZD0iTTAsMCBoMSB2NyBoLTEgeiIgY2xhc3M9Im8iLz48cGF0aCBkPSJNMiwwIGgxIHY4IGgtMSB6IiBjbGFzcz0ibyIvPjxwYXRoIGQ9Ik00LDAgaDEgdjggaC0xIHoiIGNsYXNzPSJvIi8+PHBhdGggZD0iTTYsMCBoMSB2OCBoLTEgeiIgY2xhc3M9Im8iLz48cGF0aCBkPSJNOCwzLjI1IGgxIHYxLjUgaC0xIHoiIGNsYXNzPSJvIi8+PC9zdmc+">
<title>ClickHouse Query</title> <title>ClickHouse Query</title>
<!-- Code Style: <!-- Code Style:
@ -21,26 +22,11 @@
<!-- Development Roadmap: <!-- Development Roadmap:
1. Add indication that the query was sent and when the query has been finished. 1. Support readonly servers.
Do not use any animated spinners. Just a text or check mark.
Eliminate race conditions (results from the previous query should be ignored on arrival, the previous request should be cancelled).
2. Support readonly servers.
Check if readonly = 1 (with SELECT FROM system.settings) to avoid sending settings. It can be done once on address/credentials change. Check if readonly = 1 (with SELECT FROM system.settings) to avoid sending settings. It can be done once on address/credentials change.
It can be done in background, e.g. wait 100 ms after address/credentials change and do the check. It can be done in background, e.g. wait 100 ms after address/credentials change and do the check.
Also it can provide visual indication that credentials are correct. Also it can provide visual indication that credentials are correct.
3. Add history in localstorage. Integrate with history API.
There can be a counter in localstorage, that will be appended to location #fragment.
The 'back', 'forward' buttons in browser should work.
Also there should be UI element to list all the queries from history and select from the list.
4. Trivial sharing capabilities.
Sharing is only possible when system.query_log is accessible. Read the X-ClickHouse-QueryId from the response.
Share button will: - emit SYSTEM FLUSH LOGS if not readonly; - find the query in the query_log;
- generate an URL with the query id and: server address if not equal to the URL's host; user name if not default;
indication that password should be entered in case of non-empty password.
--> -->
<style type="text/css"> <style type="text/css">
@ -273,6 +259,22 @@
{ {
color: var(--null-color); color: var(--null-color);
} }
#hourglass
{
display: none;
padding-left: 1rem;
font-size: 110%;
color: #888;
}
#check-mark
{
display: none;
padding-left: 1rem;
font-size: 110%;
color: #080;
}
</style> </style>
</head> </head>
@ -286,6 +288,8 @@
<div id="run_div"> <div id="run_div">
<button class="shadow" id="run">Run</button> <button class="shadow" id="run">Run</button>
<span class="hint">&nbsp;(Ctrl+Enter)</span> <span class="hint">&nbsp;(Ctrl+Enter)</span>
<span id="hourglass"></span>
<span id="check-mark"></span>
<span id="stats"></span> <span id="stats"></span>
<span id="toggle-dark">🌑</span><span id="toggle-light">🌞</span> <span id="toggle-dark">🌑</span><span id="toggle-light">🌞</span>
</div> </div>
@ -299,50 +303,117 @@
<script type="text/javascript"> <script type="text/javascript">
/// Incremental request number. When response is received,
/// if it's request number does not equal to the current request number, response will be ignored.
/// This is to avoid race conditions.
var request_num = 0;
/// Save query in history only if it is different.
var previous_query = '';
/// Substitute the address of the server where the page is served. /// Substitute the address of the server where the page is served.
if (location.protocol != 'file:') { if (location.protocol != 'file:') {
document.getElementById('url').value = location.origin; document.getElementById('url').value = location.origin;
} }
function post() /// Substitute user name if it's specified in the query string
var user_from_url = (new URL(window.location)).searchParams.get('user');
if (user_from_url) {
document.getElementById('user').value = user_from_url;
}
function postImpl(posted_request_num, query)
{ {
/// TODO: Avoid race condition on subsequent requests when responses may come out of order.
/// TODO: Check if URL already contains query string (append parameters). /// TODO: Check if URL already contains query string (append parameters).
var user = document.getElementById('user').value;
var password = document.getElementById('password').value;
var url = document.getElementById('url').value + var url = document.getElementById('url').value +
/// Ask server to allow cross-domain requests. /// Ask server to allow cross-domain requests.
'?add_http_cors_header=1' + '?add_http_cors_header=1' +
'&user=' + encodeURIComponent(document.getElementById('user').value) + '&user=' + encodeURIComponent(user) +
'&password=' + encodeURIComponent(document.getElementById('password').value) + '&password=' + encodeURIComponent(password) +
'&default_format=JSONCompact' + '&default_format=JSONCompact' +
/// Safety settings to prevent results that browser cannot display. /// Safety settings to prevent results that browser cannot display.
'&max_result_rows=1000&max_result_bytes=10000000&result_overflow_mode=break'; '&max_result_rows=1000&max_result_bytes=10000000&result_overflow_mode=break';
var query = document.getElementById('query').value;
var xhr = new XMLHttpRequest; var xhr = new XMLHttpRequest;
xhr.open('POST', url, true); xhr.open('POST', url, true);
xhr.send(query);
xhr.onreadystatechange = function() xhr.onreadystatechange = function()
{ {
if (this.readyState === XMLHttpRequest.DONE) { if (posted_request_num != request_num) {
if (this.status === 200) { return;
var json; } else if (this.readyState === XMLHttpRequest.DONE) {
try { json = JSON.parse(this.response); } catch (e) {} renderResponse(this.status, this.response);
if (json !== undefined && json.statistics !== undefined) {
renderResult(json); /// The query is saved in browser history (in state JSON object)
} else { /// as well as in URL fragment identifier.
renderUnparsedResult(this.response); if (query != previous_query) {
} previous_query = query;
} else { var title = "ClickHouse Query: " + query;
/// TODO: Proper rendering of network errors. history.pushState(
renderError(this.response); {
query: query,
status: this.status,
response: this.response.length > 100000 ? null : this.response /// Lower than the browser's limit.
},
title,
window.location.pathname + '?user=' + encodeURIComponent(user) + '#' + window.btoa(query));
document.title = title;
} }
} else { } else {
//console.log(this); //console.log(this);
} }
} }
document.getElementById('check-mark').style.display = 'none';
document.getElementById('hourglass').style.display = 'inline';
xhr.send(query);
}
function renderResponse(status, response) {
document.getElementById('hourglass').style.display = 'none';
if (status === 200) {
var json;
try { json = JSON.parse(response); } catch (e) {}
if (json !== undefined && json.statistics !== undefined) {
renderResult(json);
} else {
renderUnparsedResult(response);
}
document.getElementById('check-mark').style.display = 'inline';
} else {
/// TODO: Proper rendering of network errors.
renderError(response);
}
}
window.onpopstate = function(event) {
if (!event.state) {
return;
}
document.getElementById('query').value = event.state.query;
if (!event.state.response) {
clear();
return;
}
renderResponse(event.state.status, event.state.response);
};
if (window.location.hash) {
document.getElementById('query').value = window.atob(window.location.hash.substr(1));
}
function post()
{
++request_num;
var query = document.getElementById('query').value;
postImpl(request_num, query);
} }
document.getElementById('run').onclick = function() document.getElementById('run').onclick = function()
@ -350,7 +421,7 @@
post(); post();
} }
document.getElementById('query').onkeypress = function(event) document.onkeypress = function(event)
{ {
/// Firefox has code 13 for Enter and Chromium has code 10. /// Firefox has code 13 for Enter and Chromium has code 10.
if (event.ctrlKey && (event.charCode == 13 || event.charCode == 10)) { if (event.ctrlKey && (event.charCode == 13 || event.charCode == 10)) {
@ -372,6 +443,9 @@
document.getElementById('error').style.display = 'none'; document.getElementById('error').style.display = 'none';
document.getElementById('stats').innerText = ''; document.getElementById('stats').innerText = '';
document.getElementById('hourglass').style.display = 'none';
document.getElementById('check-mark').style.display = 'none';
} }
function renderResult(response) function renderResult(response)
@ -443,7 +517,7 @@
function renderError(response) function renderError(response)
{ {
clear(); clear();
document.getElementById('error').innerText = response; document.getElementById('error').innerText = response ? response : "No response.";
document.getElementById('error').style.display = 'block'; document.getElementById('error').style.display = 'block';
} }

View File

@ -80,7 +80,7 @@ public:
} }
if (!isUnsignedInteger(arguments[1])) if (!isUnsignedInteger(arguments[1]))
throw Exception("Second argument of aggregate function " + getName() + " must be integer.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); throw Exception("Second argument of aggregate function " + getName() + " must be unsigned integer.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
if (default_value.isNull()) if (default_value.isNull())
default_value = type->getDefault(); default_value = type->getDefault();

View File

@ -143,7 +143,7 @@ void LinearModelData::updateState()
void LinearModelData::predict( void LinearModelData::predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const Context & context) const const Context & context) const
@ -264,8 +264,8 @@ void Adam::merge(const IWeightsUpdater & rhs, Float64 frac, Float64 rhs_frac)
average_gradient[i] = average_gradient[i] * frac + adam_rhs.average_gradient[i] * rhs_frac; average_gradient[i] = average_gradient[i] * frac + adam_rhs.average_gradient[i] * rhs_frac;
average_squared_gradient[i] = average_squared_gradient[i] * frac + adam_rhs.average_squared_gradient[i] * rhs_frac; average_squared_gradient[i] = average_squared_gradient[i] * frac + adam_rhs.average_squared_gradient[i] * rhs_frac;
} }
beta1_powered_ *= adam_rhs.beta1_powered_; beta1_powered *= adam_rhs.beta1_powered;
beta2_powered_ *= adam_rhs.beta2_powered_; beta2_powered *= adam_rhs.beta2_powered;
} }
void Adam::update(UInt64 batch_size, std::vector<Float64> & weights, Float64 & bias, Float64 learning_rate, const std::vector<Float64> & batch_gradient) void Adam::update(UInt64 batch_size, std::vector<Float64> & weights, Float64 & bias, Float64 learning_rate, const std::vector<Float64> & batch_gradient)
@ -282,21 +282,21 @@ void Adam::update(UInt64 batch_size, std::vector<Float64> & weights, Float64 & b
for (size_t i = 0; i != average_gradient.size(); ++i) for (size_t i = 0; i != average_gradient.size(); ++i)
{ {
Float64 normed_gradient = batch_gradient[i] / batch_size; Float64 normed_gradient = batch_gradient[i] / batch_size;
average_gradient[i] = beta1_ * average_gradient[i] + (1 - beta1_) * normed_gradient; average_gradient[i] = beta1 * average_gradient[i] + (1 - beta1) * normed_gradient;
average_squared_gradient[i] = beta2_ * average_squared_gradient[i] + average_squared_gradient[i] = beta2 * average_squared_gradient[i] +
(1 - beta2_) * normed_gradient * normed_gradient; (1 - beta2) * normed_gradient * normed_gradient;
} }
for (size_t i = 0; i < weights.size(); ++i) for (size_t i = 0; i < weights.size(); ++i)
{ {
weights[i] += (learning_rate * average_gradient[i]) / weights[i] += (learning_rate * average_gradient[i]) /
((1 - beta1_powered_) * (sqrt(average_squared_gradient[i] / (1 - beta2_powered_)) + eps_)); ((1 - beta1_powered) * (sqrt(average_squared_gradient[i] / (1 - beta2_powered)) + eps));
} }
bias += (learning_rate * average_gradient[weights.size()]) / bias += (learning_rate * average_gradient[weights.size()]) /
((1 - beta1_powered_) * (sqrt(average_squared_gradient[weights.size()] / (1 - beta2_powered_)) + eps_)); ((1 - beta1_powered) * (sqrt(average_squared_gradient[weights.size()] / (1 - beta2_powered)) + eps));
beta1_powered_ *= beta1_; beta1_powered *= beta1;
beta2_powered_ *= beta2_; beta2_powered *= beta2;
} }
void Adam::addToBatch( void Adam::addToBatch(
@ -348,7 +348,7 @@ void Nesterov::update(UInt64 batch_size, std::vector<Float64> & weights, Float64
for (size_t i = 0; i < batch_gradient.size(); ++i) for (size_t i = 0; i < batch_gradient.size(); ++i)
{ {
accumulated_gradient[i] = accumulated_gradient[i] * alpha_ + (learning_rate * batch_gradient[i]) / batch_size; accumulated_gradient[i] = accumulated_gradient[i] * alpha + (learning_rate * batch_gradient[i]) / batch_size;
} }
for (size_t i = 0; i < weights.size(); ++i) for (size_t i = 0; i < weights.size(); ++i)
{ {
@ -375,9 +375,9 @@ void Nesterov::addToBatch(
std::vector<Float64> shifted_weights(weights.size()); std::vector<Float64> shifted_weights(weights.size());
for (size_t i = 0; i != shifted_weights.size(); ++i) for (size_t i = 0; i != shifted_weights.size(); ++i)
{ {
shifted_weights[i] = weights[i] + accumulated_gradient[i] * alpha_; shifted_weights[i] = weights[i] + accumulated_gradient[i] * alpha;
} }
auto shifted_bias = bias + accumulated_gradient[weights.size()] * alpha_; auto shifted_bias = bias + accumulated_gradient[weights.size()] * alpha;
gradient_computer.compute(batch_gradient, shifted_weights, shifted_bias, l2_reg_coef, target, columns, row_num); gradient_computer.compute(batch_gradient, shifted_weights, shifted_bias, l2_reg_coef, target, columns, row_num);
} }
@ -411,7 +411,7 @@ void Momentum::update(UInt64 batch_size, std::vector<Float64> & weights, Float64
for (size_t i = 0; i < batch_gradient.size(); ++i) for (size_t i = 0; i < batch_gradient.size(); ++i)
{ {
accumulated_gradient[i] = accumulated_gradient[i] * alpha_ + (learning_rate * batch_gradient[i]) / batch_size; accumulated_gradient[i] = accumulated_gradient[i] * alpha + (learning_rate * batch_gradient[i]) / batch_size;
} }
for (size_t i = 0; i < weights.size(); ++i) for (size_t i = 0; i < weights.size(); ++i)
{ {
@ -448,7 +448,7 @@ void IWeightsUpdater::addToBatch(
void LogisticRegression::predict( void LogisticRegression::predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
@ -516,7 +516,7 @@ void LogisticRegression::compute(
void LinearRegression::predict( void LinearRegression::predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,

View File

@ -23,7 +23,7 @@ GradientComputer class computes gradient according to its loss function
class IGradientComputer class IGradientComputer
{ {
public: public:
IGradientComputer() {} IGradientComputer() = default;
virtual ~IGradientComputer() = default; virtual ~IGradientComputer() = default;
@ -39,7 +39,7 @@ public:
virtual void predict( virtual void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
@ -51,7 +51,7 @@ public:
class LinearRegression : public IGradientComputer class LinearRegression : public IGradientComputer
{ {
public: public:
LinearRegression() {} LinearRegression() = default;
void compute( void compute(
std::vector<Float64> & batch_gradient, std::vector<Float64> & batch_gradient,
@ -64,7 +64,7 @@ public:
void predict( void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
@ -76,7 +76,7 @@ public:
class LogisticRegression : public IGradientComputer class LogisticRegression : public IGradientComputer
{ {
public: public:
LogisticRegression() {} LogisticRegression() = default;
void compute( void compute(
std::vector<Float64> & batch_gradient, std::vector<Float64> & batch_gradient,
@ -89,7 +89,7 @@ public:
void predict( void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const std::vector<Float64> & weights, const std::vector<Float64> & weights,
@ -147,9 +147,9 @@ public:
class Momentum : public IWeightsUpdater class Momentum : public IWeightsUpdater
{ {
public: public:
Momentum() {} Momentum() = default;
Momentum(Float64 alpha) : alpha_(alpha) {} explicit Momentum(Float64 alpha_) : alpha(alpha_) {}
void update(UInt64 batch_size, std::vector<Float64> & weights, Float64 & bias, Float64 learning_rate, const std::vector<Float64> & batch_gradient) override; void update(UInt64 batch_size, std::vector<Float64> & weights, Float64 & bias, Float64 learning_rate, const std::vector<Float64> & batch_gradient) override;
@ -160,7 +160,7 @@ public:
void read(ReadBuffer & buf) override; void read(ReadBuffer & buf) override;
private: private:
Float64 alpha_{0.1}; Float64 alpha{0.1};
std::vector<Float64> accumulated_gradient; std::vector<Float64> accumulated_gradient;
}; };
@ -168,9 +168,9 @@ private:
class Nesterov : public IWeightsUpdater class Nesterov : public IWeightsUpdater
{ {
public: public:
Nesterov() {} Nesterov() = default;
Nesterov(Float64 alpha) : alpha_(alpha) {} explicit Nesterov(Float64 alpha_) : alpha(alpha_) {}
void addToBatch( void addToBatch(
std::vector<Float64> & batch_gradient, std::vector<Float64> & batch_gradient,
@ -191,7 +191,7 @@ public:
void read(ReadBuffer & buf) override; void read(ReadBuffer & buf) override;
private: private:
const Float64 alpha_ = 0.9; const Float64 alpha = 0.9;
std::vector<Float64> accumulated_gradient; std::vector<Float64> accumulated_gradient;
}; };
@ -201,8 +201,8 @@ class Adam : public IWeightsUpdater
public: public:
Adam() Adam()
{ {
beta1_powered_ = beta1_; beta1_powered = beta1;
beta2_powered_ = beta2_; beta2_powered = beta2;
} }
void addToBatch( void addToBatch(
@ -225,11 +225,11 @@ public:
private: private:
/// beta1 and beta2 hyperparameters have such recommended values /// beta1 and beta2 hyperparameters have such recommended values
const Float64 beta1_ = 0.9; const Float64 beta1 = 0.9;
const Float64 beta2_ = 0.999; const Float64 beta2 = 0.999;
const Float64 eps_ = 0.000001; const Float64 eps = 0.000001;
Float64 beta1_powered_; Float64 beta1_powered;
Float64 beta2_powered_; Float64 beta2_powered;
std::vector<Float64> average_gradient; std::vector<Float64> average_gradient;
std::vector<Float64> average_squared_gradient; std::vector<Float64> average_squared_gradient;
@ -241,7 +241,7 @@ private:
class LinearModelData class LinearModelData
{ {
public: public:
LinearModelData() {} LinearModelData() = default;
LinearModelData( LinearModelData(
Float64 learning_rate_, Float64 learning_rate_,
@ -261,7 +261,7 @@ public:
void predict( void predict(
ColumnVector<Float64>::Container & container, ColumnVector<Float64>::Container & container,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const Context & context) const; const Context & context) const;
@ -360,7 +360,7 @@ public:
void predictValues( void predictValues(
ConstAggregateDataPtr place, ConstAggregateDataPtr place,
IColumn & to, IColumn & to,
ColumnsWithTypeAndName & arguments, const ColumnsWithTypeAndName & arguments,
size_t offset, size_t offset,
size_t limit, size_t limit,
const Context & context) const override const Context & context) const override

View File

@ -61,7 +61,7 @@ public:
throw Exception("Prediction is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Prediction is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
virtual ~IAggregateFunction() {} virtual ~IAggregateFunction() = default;
/** Data manipulating functions. */ /** Data manipulating functions. */
@ -114,7 +114,7 @@ public:
virtual void predictValues( virtual void predictValues(
ConstAggregateDataPtr /* place */, ConstAggregateDataPtr /* place */,
IColumn & /*to*/, IColumn & /*to*/,
ColumnsWithTypeAndName & /*arguments*/, const ColumnsWithTypeAndName & /*arguments*/,
size_t /*offset*/, size_t /*offset*/,
size_t /*limit*/, size_t /*limit*/,
const Context & /*context*/) const const Context & /*context*/) const

View File

@ -161,7 +161,7 @@ MutableColumnPtr ColumnAggregateFunction::convertToValues(MutableColumnPtr colum
return res; return res;
} }
MutableColumnPtr ColumnAggregateFunction::predictValues(ColumnsWithTypeAndName & arguments, const Context & context) const MutableColumnPtr ColumnAggregateFunction::predictValues(const ColumnsWithTypeAndName & arguments, const Context & context) const
{ {
MutableColumnPtr res = func->getReturnTypeToPredict()->createColumn(); MutableColumnPtr res = func->getReturnTypeToPredict()->createColumn();
res->reserve(data.size()); res->reserve(data.size());

View File

@ -119,7 +119,7 @@ public:
const char * getFamilyName() const override { return "AggregateFunction"; } const char * getFamilyName() const override { return "AggregateFunction"; }
TypeIndex getDataType() const override { return TypeIndex::AggregateFunction; } TypeIndex getDataType() const override { return TypeIndex::AggregateFunction; }
MutableColumnPtr predictValues(ColumnsWithTypeAndName & arguments, const Context & context) const; MutableColumnPtr predictValues(const ColumnsWithTypeAndName & arguments, const Context & context) const;
size_t size() const override size_t size() const override
{ {

View File

@ -511,19 +511,30 @@ void TestKeeper::processingThread()
if (expired) if (expired)
break; break;
if (info.watch)
{
auto & watches_type = dynamic_cast<const ListRequest *>(info.request.get())
? list_watches
: watches;
watches_type[info.request->getPath()].emplace_back(std::move(info.watch));
}
++zxid; ++zxid;
info.request->addRootPath(root_path); info.request->addRootPath(root_path);
auto [response, _] = info.request->process(container, zxid); auto [response, _] = info.request->process(container, zxid);
if (info.watch)
{
/// To be compatible with real ZooKeeper we add watch if request was successful (i.e. node exists)
/// or if it was exists request which allows to add watches for non existing nodes.
if (response->error == Error::ZOK)
{
auto & watches_type = dynamic_cast<const ListRequest *>(info.request.get())
? list_watches
: watches;
watches_type[info.request->getPath()].emplace_back(std::move(info.watch));
}
else if (response->error == Error::ZNONODE && dynamic_cast<const ExistsRequest *>(info.request.get()))
{
watches[info.request->getPath()].emplace_back(std::move(info.watch));
}
}
if (response->error == Error::ZOK) if (response->error == Error::ZOK)
info.request->processWatches(watches, list_watches); info.request->processWatches(watches, list_watches);

View File

@ -6,6 +6,7 @@
#include <Core/MySQL/PacketsProtocolText.h> #include <Core/MySQL/PacketsProtocolText.h>
#include <Core/MySQL/PacketsReplication.h> #include <Core/MySQL/PacketsReplication.h>
#include <Core/MySQL/MySQLReplication.h> #include <Core/MySQL/MySQLReplication.h>
#include <Poco/String.h>
namespace DB namespace DB
{ {
@ -132,11 +133,19 @@ void MySQLClient::ping()
writeCommand(Command::COM_PING, ""); writeCommand(Command::COM_PING, "");
} }
void MySQLClient::startBinlogDumpGTID(UInt32 slave_id, String replicate_db, String gtid_str) void MySQLClient::setBinlogChecksum(const String & binlog_checksum)
{ {
/// Set binlog checksum to CRC32. replication.setChecksumSignatureLength(Poco::toUpper(binlog_checksum) == "NONE" ? 0 : 4);
String checksum = "CRC32"; }
writeCommand(Command::COM_QUERY, "SET @master_binlog_checksum = '" + checksum + "'");
void MySQLClient::startBinlogDumpGTID(UInt32 slave_id, String replicate_db, String gtid_str, const String & binlog_checksum)
{
/// Maybe CRC32 or NONE. mysqlbinlog.cc use NONE, see its below comments:
/// Make a notice to the server that this client is checksum-aware.
/// It does not need the first fake Rotate necessary checksummed.
writeCommand(Command::COM_QUERY, "SET @master_binlog_checksum = 'CRC32'");
setBinlogChecksum(binlog_checksum);
/// Set heartbeat 1s. /// Set heartbeat 1s.
UInt64 period_ns = (1 * 1e9); UInt64 period_ns = (1 * 1e9);

View File

@ -29,10 +29,12 @@ public:
void disconnect(); void disconnect();
void ping(); void ping();
void setBinlogChecksum(const String & binlog_checksum);
/// Start replication stream by GTID. /// Start replication stream by GTID.
/// replicate_db: replication database schema, events from other databases will be ignored. /// replicate_db: replication database schema, events from other databases will be ignored.
/// gtid: executed gtid sets format like 'hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh:x-y'. /// gtid: executed gtid sets format like 'hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh:x-y'.
void startBinlogDumpGTID(UInt32 slave_id, String replicate_db, String gtid); void startBinlogDumpGTID(UInt32 slave_id, String replicate_db, String gtid, const String & binlog_checksum);
BinlogEventPtr readOneBinlogEvent(UInt64 milliseconds = 0); BinlogEventPtr readOneBinlogEvent(UInt64 milliseconds = 0);
Position getPosition() const { return replication.getPosition(); } Position getPosition() const { return replication.getPosition(); }

View File

@ -57,7 +57,6 @@ namespace MySQLReplication
payload.readStrict(reinterpret_cast<char *>(&create_timestamp), 4); payload.readStrict(reinterpret_cast<char *>(&create_timestamp), 4);
payload.readStrict(reinterpret_cast<char *>(&event_header_length), 1); payload.readStrict(reinterpret_cast<char *>(&event_header_length), 1);
assert(event_header_length == EVENT_HEADER_LENGTH); assert(event_header_length == EVENT_HEADER_LENGTH);
readStringUntilEOF(event_type_header_length, payload); readStringUntilEOF(event_type_header_length, payload);
} }
@ -745,7 +744,7 @@ namespace MySQLReplication
// skip the generic response packets header flag. // skip the generic response packets header flag.
payload.ignore(1); payload.ignore(1);
MySQLBinlogEventReadBuffer event_payload(payload); MySQLBinlogEventReadBuffer event_payload(payload, checksum_signature_length);
EventHeader event_header; EventHeader event_header;
event_header.parse(event_payload); event_header.parse(event_payload);

View File

@ -526,6 +526,8 @@ namespace MySQLReplication
virtual BinlogEventPtr readOneEvent() = 0; virtual BinlogEventPtr readOneEvent() = 0;
virtual void setReplicateDatabase(String db) = 0; virtual void setReplicateDatabase(String db) = 0;
virtual void setGTIDSets(GTIDSets sets) = 0; virtual void setGTIDSets(GTIDSets sets) = 0;
virtual void setChecksumSignatureLength(size_t checksum_signature_length_) = 0;
virtual ~IFlavor() override = default; virtual ~IFlavor() override = default;
}; };
@ -538,12 +540,14 @@ namespace MySQLReplication
BinlogEventPtr readOneEvent() override { return event; } BinlogEventPtr readOneEvent() override { return event; }
void setReplicateDatabase(String db) override { replicate_do_db = std::move(db); } void setReplicateDatabase(String db) override { replicate_do_db = std::move(db); }
void setGTIDSets(GTIDSets sets) override { position.gtid_sets = std::move(sets); } void setGTIDSets(GTIDSets sets) override { position.gtid_sets = std::move(sets); }
void setChecksumSignatureLength(size_t checksum_signature_length_) override { checksum_signature_length = checksum_signature_length_; }
private: private:
Position position; Position position;
BinlogEventPtr event; BinlogEventPtr event;
String replicate_do_db; String replicate_do_db;
std::shared_ptr<TableMapEvent> table_map; std::shared_ptr<TableMapEvent> table_map;
size_t checksum_signature_length = 4;
inline bool do_replicate() { return (replicate_do_db.empty() || table_map->schema == replicate_do_db); } inline bool do_replicate() { return (replicate_do_db.empty() || table_map->schema == replicate_do_db); }
}; };

View File

@ -304,7 +304,8 @@ int main(int argc, char ** argv)
"user", boost::program_options::value<std::string>()->default_value("root"), "master user")( "user", boost::program_options::value<std::string>()->default_value("root"), "master user")(
"password", boost::program_options::value<std::string>()->required(), "master password")( "password", boost::program_options::value<std::string>()->required(), "master password")(
"gtid", boost::program_options::value<std::string>()->default_value(""), "executed GTID sets")( "gtid", boost::program_options::value<std::string>()->default_value(""), "executed GTID sets")(
"db", boost::program_options::value<std::string>()->required(), "replicate do db"); "db", boost::program_options::value<std::string>()->required(), "replicate do db")(
"binlog_checksum", boost::program_options::value<std::string>()->default_value("CRC32"), "master binlog_checksum");
boost::program_options::variables_map options; boost::program_options::variables_map options;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), options); boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), options);
@ -319,6 +320,7 @@ int main(int argc, char ** argv)
auto master_password = options.at("password").as<DB::String>(); auto master_password = options.at("password").as<DB::String>();
auto gtid_sets = options.at("gtid").as<DB::String>(); auto gtid_sets = options.at("gtid").as<DB::String>();
auto replicate_db = options.at("db").as<DB::String>(); auto replicate_db = options.at("db").as<DB::String>();
auto binlog_checksum = options.at("binlog_checksum").as<String>();
std::cerr << "Master Host: " << host << ", Port: " << port << ", User: " << master_user << ", Password: " << master_password std::cerr << "Master Host: " << host << ", Port: " << port << ", User: " << master_user << ", Password: " << master_password
<< ", Replicate DB: " << replicate_db << ", GTID: " << gtid_sets << std::endl; << ", Replicate DB: " << replicate_db << ", GTID: " << gtid_sets << std::endl;
@ -328,7 +330,7 @@ int main(int argc, char ** argv)
/// Connect to the master. /// Connect to the master.
slave.connect(); slave.connect();
slave.startBinlogDumpGTID(slave_id, replicate_db, gtid_sets); slave.startBinlogDumpGTID(slave_id, replicate_db, gtid_sets, binlog_checksum);
WriteBufferFromOStream cerr(std::cerr); WriteBufferFromOStream cerr(std::cerr);

View File

@ -44,10 +44,10 @@ namespace
} }
} }
DatabaseDictionary::DatabaseDictionary(const String & name_, const Context & global_context_) DatabaseDictionary::DatabaseDictionary(const String & name_, const Context & context_)
: IDatabase(name_) : IDatabase(name_)
, log(&Poco::Logger::get("DatabaseDictionary(" + database_name + ")")) , log(&Poco::Logger::get("DatabaseDictionary(" + database_name + ")"))
, global_context(global_context_.getGlobalContext()) , global_context(context_.getGlobalContext())
{ {
} }

View File

@ -22,7 +22,7 @@ namespace DB
class DatabaseDictionary final : public IDatabase class DatabaseDictionary final : public IDatabase
{ {
public: public:
DatabaseDictionary(const String & name_, const Context & global_context); DatabaseDictionary(const String & name_, const Context & context_);
String getEngineName() const override String getEngineName() const override
{ {

View File

@ -67,14 +67,14 @@ namespace
} }
void tryAttachDictionary(const ASTPtr & query, DatabaseOrdinary & database, const String & metadata_path) void tryAttachDictionary(const ASTPtr & query, DatabaseOrdinary & database, const String & metadata_path, const Context & context)
{ {
auto & create_query = query->as<ASTCreateQuery &>(); auto & create_query = query->as<ASTCreateQuery &>();
assert(create_query.is_dictionary); assert(create_query.is_dictionary);
try try
{ {
Poco::File meta_file(metadata_path); Poco::File meta_file(metadata_path);
auto config = getDictionaryConfigurationFromAST(create_query, database.getDatabaseName()); auto config = getDictionaryConfigurationFromAST(create_query, context, database.getDatabaseName());
time_t modification_time = meta_file.getLastModified().epochTime(); time_t modification_time = meta_file.getLastModified().epochTime();
database.attachDictionary(create_query.table, DictionaryAttachInfo{query, config, modification_time}); database.attachDictionary(create_query.table, DictionaryAttachInfo{query, config, modification_time});
} }
@ -190,7 +190,7 @@ void DatabaseOrdinary::loadStoredObjects(Context & context, bool has_force_resto
auto create_query = query->as<const ASTCreateQuery &>(); auto create_query = query->as<const ASTCreateQuery &>();
if (create_query.is_dictionary) if (create_query.is_dictionary)
{ {
tryAttachDictionary(query, *this, getMetadataPath() + name); tryAttachDictionary(query, *this, getMetadataPath() + name, context);
/// Messages, so that it's not boring to wait for the server to load for a long time. /// Messages, so that it's not boring to wait for the server to load for a long time.
logAboutProgress(log, ++dictionaries_processed, total_dictionaries, watch); logAboutProgress(log, ++dictionaries_processed, total_dictionaries, watch);

View File

@ -176,7 +176,7 @@ void DatabaseWithDictionaries::createDictionary(const Context & context, const S
/// Add a temporary repository containing the dictionary. /// Add a temporary repository containing the dictionary.
/// We need this temp repository to try loading the dictionary before actually attaching it to the database. /// We need this temp repository to try loading the dictionary before actually attaching it to the database.
auto temp_repository = external_loader.addConfigRepository(std::make_unique<ExternalLoaderTempConfigRepository>( auto temp_repository = external_loader.addConfigRepository(std::make_unique<ExternalLoaderTempConfigRepository>(
getDatabaseName(), dictionary_metadata_tmp_path, getDictionaryConfigurationFromAST(query->as<const ASTCreateQuery &>()))); getDatabaseName(), dictionary_metadata_tmp_path, getDictionaryConfigurationFromAST(query->as<const ASTCreateQuery &>(), context)));
bool lazy_load = context.getConfigRef().getBool("dictionaries_lazy_load", true); bool lazy_load = context.getConfigRef().getBool("dictionaries_lazy_load", true);
if (!lazy_load) if (!lazy_load)
@ -186,7 +186,7 @@ void DatabaseWithDictionaries::createDictionary(const Context & context, const S
external_loader.load(dict_id.getInternalDictionaryName()); external_loader.load(dict_id.getInternalDictionaryName());
} }
auto config = getDictionaryConfigurationFromAST(query->as<const ASTCreateQuery &>()); auto config = getDictionaryConfigurationFromAST(query->as<const ASTCreateQuery &>(), context);
attachDictionary(dictionary_name, DictionaryAttachInfo{query, config, time(nullptr)}); attachDictionary(dictionary_name, DictionaryAttachInfo{query, config, time(nullptr)});
SCOPE_EXIT({ SCOPE_EXIT({
if (!succeeded) if (!succeeded)

View File

@ -13,6 +13,7 @@
# include <Databases/MySQL/FetchTablesColumnsList.h> # include <Databases/MySQL/FetchTablesColumnsList.h>
# include <Formats/MySQLBlockInputStream.h> # include <Formats/MySQLBlockInputStream.h>
# include <IO/Operators.h> # include <IO/Operators.h>
# include <Interpreters/Context.h>
# include <Parsers/ASTCreateQuery.h> # include <Parsers/ASTCreateQuery.h>
# include <Parsers/ASTFunction.h> # include <Parsers/ASTFunction.h>
# include <Parsers/ParserCreateQuery.h> # include <Parsers/ParserCreateQuery.h>

View File

@ -91,6 +91,29 @@ void MaterializeMetadata::fetchMasterStatus(mysqlxx::PoolWithFailover::Entry & c
executed_gtid_set = (*master_status.getByPosition(4).column)[0].safeGet<String>(); executed_gtid_set = (*master_status.getByPosition(4).column)[0].safeGet<String>();
} }
void MaterializeMetadata::fetchMasterVariablesValue(const mysqlxx::PoolWithFailover::Entry & connection)
{
Block variables_header{
{std::make_shared<DataTypeString>(), "Variable_name"},
{std::make_shared<DataTypeString>(), "Value"}
};
const String & fetch_query = "SHOW VARIABLES WHERE Variable_name = 'binlog_checksum'";
MySQLBlockInputStream variables_input(connection, fetch_query, variables_header, DEFAULT_BLOCK_SIZE);
while (Block variables_block = variables_input.read())
{
ColumnPtr variables_name = variables_block.getByName("Variable_name").column;
ColumnPtr variables_value = variables_block.getByName("Value").column;
for (size_t index = 0; index < variables_block.rows(); ++index)
{
if (variables_name->getDataAt(index) == "binlog_checksum")
binlog_checksum = variables_value->getDataAt(index).toString();
}
}
}
static Block getShowMasterLogHeader(const String & mysql_version) static Block getShowMasterLogHeader(const String & mysql_version)
{ {
if (startsWith(mysql_version, "5.")) if (startsWith(mysql_version, "5."))
@ -241,6 +264,7 @@ MaterializeMetadata::MaterializeMetadata(
locked_tables = true; locked_tables = true;
fetchMasterStatus(connection); fetchMasterStatus(connection);
fetchMasterVariablesValue(connection);
connection->query("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;").execute(); connection->query("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;").execute();
connection->query("START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */;").execute(); connection->query("START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */;").execute();

View File

@ -34,10 +34,13 @@ struct MaterializeMetadata
size_t data_version = 1; size_t data_version = 1;
size_t meta_version = 2; size_t meta_version = 2;
String binlog_checksum = "CRC32";
std::unordered_map<String, String> need_dumping_tables; std::unordered_map<String, String> need_dumping_tables;
void fetchMasterStatus(mysqlxx::PoolWithFailover::Entry & connection); void fetchMasterStatus(mysqlxx::PoolWithFailover::Entry & connection);
void fetchMasterVariablesValue(const mysqlxx::PoolWithFailover::Entry & connection);
bool checkBinlogFileExists(mysqlxx::PoolWithFailover::Entry & connection, const String & mysql_version) const; bool checkBinlogFileExists(mysqlxx::PoolWithFailover::Entry & connection, const String & mysql_version) const;
void transaction(const MySQLReplication::Position & position, const std::function<void()> & fun); void transaction(const MySQLReplication::Position & position, const std::function<void()> & fun);

View File

@ -364,7 +364,7 @@ std::optional<MaterializeMetadata> MaterializeMySQLSyncThread::prepareSynchroniz
connection->query("COMMIT").execute(); connection->query("COMMIT").execute();
client.connect(); client.connect();
client.startBinlogDumpGTID(randomNumber(), mysql_database_name, metadata.executed_gtid_set); client.startBinlogDumpGTID(randomNumber(), mysql_database_name, metadata.executed_gtid_set, metadata.binlog_checksum);
return metadata; return metadata;
} }
catch (...) catch (...)
@ -648,16 +648,27 @@ void MaterializeMySQLSyncThread::onEvent(Buffers & buffers, const BinlogEventPtr
metadata.transaction(position_before_ddl, [&]() { buffers.commit(global_context); }); metadata.transaction(position_before_ddl, [&]() { buffers.commit(global_context); });
metadata.transaction(client.getPosition(),[&](){ executeDDLAtomic(query_event); }); metadata.transaction(client.getPosition(),[&](){ executeDDLAtomic(query_event); });
} }
else if (receive_event->header.type != HEARTBEAT_EVENT) else
{ {
const auto & dump_event_message = [&]() /// MYSQL_UNHANDLED_EVENT
if (receive_event->header.type == ROTATE_EVENT)
{ {
WriteBufferFromOwnString buf; /// Some behaviors(such as changing the value of "binlog_checksum") rotate the binlog file.
receive_event->dump(buf); /// To ensure that the synchronization continues, we need to handle these events
return buf.str(); metadata.fetchMasterVariablesValue(pool.get());
}; client.setBinlogChecksum(metadata.binlog_checksum);
}
else if (receive_event->header.type != HEARTBEAT_EVENT)
{
const auto & dump_event_message = [&]()
{
WriteBufferFromOwnString buf;
receive_event->dump(buf);
return buf.str();
};
LOG_DEBUG(log, "Skip MySQL event: \n {}", dump_event_message()); LOG_DEBUG(log, "Skip MySQL event: \n {}", dump_event_message());
}
} }
} }

View File

@ -62,7 +62,7 @@ DictionaryPtr DictionaryFactory::create(
DictionaryPtr DictionaryFactory::create(const std::string & name, const ASTCreateQuery & ast, const Context & context) const DictionaryPtr DictionaryFactory::create(const std::string & name, const ASTCreateQuery & ast, const Context & context) const
{ {
auto configuration = getDictionaryConfigurationFromAST(ast); auto configuration = getDictionaryConfigurationFromAST(ast, context);
return DictionaryFactory::create(name, *configuration, "dictionary", context, true); return DictionaryFactory::create(name, *configuration, "dictionary", context, true);
} }

View File

@ -120,7 +120,7 @@ XDBCDictionarySource::XDBCDictionarySource(
, invalidate_query{config_.getString(config_prefix_ + ".invalidate_query", "")} , invalidate_query{config_.getString(config_prefix_ + ".invalidate_query", "")}
, bridge_helper{bridge_} , bridge_helper{bridge_}
, timeouts{ConnectionTimeouts::getHTTPTimeouts(context_)} , timeouts{ConnectionTimeouts::getHTTPTimeouts(context_)}
, global_context(context_) , global_context(context_.getGlobalContext())
{ {
bridge_url = bridge_helper->getMainURI(); bridge_url = bridge_helper->getMainURI();

View File

@ -14,6 +14,7 @@
#include <Parsers/ASTFunctionWithKeyValueArguments.h> #include <Parsers/ASTFunctionWithKeyValueArguments.h>
#include <Parsers/ASTDictionaryAttributeDeclaration.h> #include <Parsers/ASTDictionaryAttributeDeclaration.h>
#include <Dictionaries/DictionaryFactory.h> #include <Dictionaries/DictionaryFactory.h>
#include <Functions/FunctionFactory.h>
namespace DB namespace DB
{ {
@ -356,7 +357,8 @@ NamesToTypeNames buildDictionaryAttributesConfiguration(
void buildConfigurationFromFunctionWithKeyValueArguments( void buildConfigurationFromFunctionWithKeyValueArguments(
AutoPtr<Document> doc, AutoPtr<Document> doc,
AutoPtr<Element> root, AutoPtr<Element> root,
const ASTExpressionList * ast_expr_list) const ASTExpressionList * ast_expr_list,
const Context & context)
{ {
const auto & children = ast_expr_list->children; const auto & children = ast_expr_list->children;
for (size_t i = 0; i != children.size(); ++i) for (size_t i = 0; i != children.size(); ++i)
@ -365,19 +367,30 @@ void buildConfigurationFromFunctionWithKeyValueArguments(
AutoPtr<Element> current_xml_element(doc->createElement(pair->first)); AutoPtr<Element> current_xml_element(doc->createElement(pair->first));
root->appendChild(current_xml_element); root->appendChild(current_xml_element);
if (const auto * identifier = pair->second->as<const ASTIdentifier>(); identifier) if (const auto * identifier = pair->second->as<const ASTIdentifier>())
{ {
AutoPtr<Text> value(doc->createTextNode(identifier->name())); AutoPtr<Text> value(doc->createTextNode(identifier->name()));
current_xml_element->appendChild(value); current_xml_element->appendChild(value);
} }
else if (const auto * literal = pair->second->as<const ASTLiteral>(); literal) else if (const auto * literal = pair->second->as<const ASTLiteral>())
{ {
AutoPtr<Text> value(doc->createTextNode(getFieldAsString(literal->value))); AutoPtr<Text> value(doc->createTextNode(getFieldAsString(literal->value)));
current_xml_element->appendChild(value); current_xml_element->appendChild(value);
} }
else if (const auto * list = pair->second->as<const ASTExpressionList>(); list) else if (const auto * list = pair->second->as<const ASTExpressionList>())
{ {
buildConfigurationFromFunctionWithKeyValueArguments(doc, current_xml_element, list); buildConfigurationFromFunctionWithKeyValueArguments(doc, current_xml_element, list, context);
}
else if (const auto * func = pair->second->as<ASTFunction>())
{
auto builder = FunctionFactory::instance().tryGet(func->name, context);
auto function = builder->build({});
auto result = function->execute({}, {}, 0);
Field value;
result->get(0, value);
AutoPtr<Text> text_value(doc->createTextNode(getFieldAsString(value)));
current_xml_element->appendChild(text_value);
} }
else else
{ {
@ -406,13 +419,14 @@ void buildSourceConfiguration(
AutoPtr<Document> doc, AutoPtr<Document> doc,
AutoPtr<Element> root, AutoPtr<Element> root,
const ASTFunctionWithKeyValueArguments * source, const ASTFunctionWithKeyValueArguments * source,
const ASTDictionarySettings * settings) const ASTDictionarySettings * settings,
const Context & context)
{ {
AutoPtr<Element> outer_element(doc->createElement("source")); AutoPtr<Element> outer_element(doc->createElement("source"));
root->appendChild(outer_element); root->appendChild(outer_element);
AutoPtr<Element> source_element(doc->createElement(source->name)); AutoPtr<Element> source_element(doc->createElement(source->name));
outer_element->appendChild(source_element); outer_element->appendChild(source_element);
buildConfigurationFromFunctionWithKeyValueArguments(doc, source_element, source->elements->as<const ASTExpressionList>()); buildConfigurationFromFunctionWithKeyValueArguments(doc, source_element, source->elements->as<const ASTExpressionList>(), context);
if (settings != nullptr) if (settings != nullptr)
{ {
@ -466,7 +480,8 @@ void checkPrimaryKey(const NamesToTypeNames & all_attrs, const Names & key_attrs
} }
DictionaryConfigurationPtr getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const std::string & database_) DictionaryConfigurationPtr
getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const Context & context, const std::string & database_)
{ {
checkAST(query); checkAST(query);
@ -510,7 +525,7 @@ DictionaryConfigurationPtr getDictionaryConfigurationFromAST(const ASTCreateQuer
buildPrimaryKeyConfiguration(xml_document, structure_element, complex, pk_attrs, query.dictionary_attributes_list); buildPrimaryKeyConfiguration(xml_document, structure_element, complex, pk_attrs, query.dictionary_attributes_list);
buildLayoutConfiguration(xml_document, current_dictionary, dictionary_layout); buildLayoutConfiguration(xml_document, current_dictionary, dictionary_layout);
buildSourceConfiguration(xml_document, current_dictionary, query.dictionary->source, query.dictionary->dict_settings); buildSourceConfiguration(xml_document, current_dictionary, query.dictionary->source, query.dictionary->dict_settings, context);
buildLifetimeConfiguration(xml_document, current_dictionary, query.dictionary->lifetime); buildLifetimeConfiguration(xml_document, current_dictionary, query.dictionary->lifetime);
if (query.dictionary->range) if (query.dictionary->range)

View File

@ -10,5 +10,6 @@ using DictionaryConfigurationPtr = Poco::AutoPtr<Poco::Util::AbstractConfigurati
/// Convert dictionary AST to Poco::AbstractConfiguration /// Convert dictionary AST to Poco::AbstractConfiguration
/// This function is necessary because all loadable objects configuration are Poco::AbstractConfiguration /// This function is necessary because all loadable objects configuration are Poco::AbstractConfiguration
/// Can throw exception if query is ill-formed /// Can throw exception if query is ill-formed
DictionaryConfigurationPtr getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const std::string & database_ = ""); DictionaryConfigurationPtr
getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const Context & context, const std::string & database_ = "");
} }

View File

@ -1,12 +1,14 @@
#include <common/types.h> #include <Dictionaries/getDictionaryConfigurationFromAST.h>
#include <Poco/Util/XMLConfiguration.h> #include <Dictionaries/registerDictionaries.h>
#include <Interpreters/Context.h>
#include <Parsers/ASTCreateQuery.h> #include <Parsers/ASTCreateQuery.h>
#include <Parsers/DumpASTNode.h> #include <Parsers/DumpASTNode.h>
#include <Parsers/ParserCreateQuery.h> #include <Parsers/ParserCreateQuery.h>
#include <Parsers/formatAST.h> #include <Parsers/formatAST.h>
#include <Parsers/parseQuery.h> #include <Parsers/parseQuery.h>
#include <Dictionaries/getDictionaryConfigurationFromAST.h> #include <Poco/Util/XMLConfiguration.h>
#include <Dictionaries/registerDictionaries.h> #include <Common/tests/gtest_global_context.h>
#include <common/types.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -47,7 +49,7 @@ TEST(ConvertDictionaryAST, SimpleDictConfiguration)
ParserCreateDictionaryQuery parser; ParserCreateDictionaryQuery parser;
ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0); ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0);
ASTCreateQuery * create = ast->as<ASTCreateQuery>(); ASTCreateQuery * create = ast->as<ASTCreateQuery>();
DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create); DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create, getContext().context);
/// name /// name
EXPECT_EQ(config->getString("dictionary.database"), "test"); EXPECT_EQ(config->getString("dictionary.database"), "test");
@ -115,7 +117,7 @@ TEST(ConvertDictionaryAST, TrickyAttributes)
ParserCreateDictionaryQuery parser; ParserCreateDictionaryQuery parser;
ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0); ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0);
ASTCreateQuery * create = ast->as<ASTCreateQuery>(); ASTCreateQuery * create = ast->as<ASTCreateQuery>();
DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create); DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create, getContext().context);
Poco::Util::AbstractConfiguration::Keys keys; Poco::Util::AbstractConfiguration::Keys keys;
config->keys("dictionary.structure", keys); config->keys("dictionary.structure", keys);
@ -160,7 +162,7 @@ TEST(ConvertDictionaryAST, ComplexKeyAndLayoutWithParams)
ParserCreateDictionaryQuery parser; ParserCreateDictionaryQuery parser;
ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0); ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0);
ASTCreateQuery * create = ast->as<ASTCreateQuery>(); ASTCreateQuery * create = ast->as<ASTCreateQuery>();
DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create); DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create, getContext().context);
Poco::Util::AbstractConfiguration::Keys keys; Poco::Util::AbstractConfiguration::Keys keys;
config->keys("dictionary.structure.key", keys); config->keys("dictionary.structure.key", keys);
@ -211,7 +213,7 @@ TEST(ConvertDictionaryAST, ComplexSource)
ParserCreateDictionaryQuery parser; ParserCreateDictionaryQuery parser;
ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0); ASTPtr ast = parseQuery(parser, input.data(), input.data() + input.size(), "", 0, 0);
ASTCreateQuery * create = ast->as<ASTCreateQuery>(); ASTCreateQuery * create = ast->as<ASTCreateQuery>();
DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create); DictionaryConfigurationPtr config = getDictionaryConfigurationFromAST(*create, getContext().context);
/// source /// source
EXPECT_EQ(config->getString("dictionary.source.mysql.host"), "localhost"); EXPECT_EQ(config->getString("dictionary.source.mysql.host"), "localhost");
EXPECT_EQ(config->getInt("dictionary.source.mysql.port"), 9000); EXPECT_EQ(config->getInt("dictionary.source.mysql.port"), 9000);

View File

@ -116,7 +116,7 @@ template <typename FromDataType, typename ToDataType>
struct CustomWeekTransformImpl struct CustomWeekTransformImpl
{ {
template <typename Transform> template <typename Transform>
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/, Transform transform = {}) static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/, Transform transform = {})
{ {
const auto op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>{std::move(transform)}; const auto op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>{std::move(transform)};

View File

@ -683,7 +683,7 @@ struct Transformer
template <typename FromDataType, typename ToDataType, typename Transform> template <typename FromDataType, typename ToDataType, typename Transform>
struct DateTimeTransformImpl struct DateTimeTransformImpl
{ {
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/, const Transform & transform = {}) static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/, const Transform & transform = {})
{ {
using Op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>; using Op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>;

View File

@ -91,7 +91,7 @@ public:
return std::make_shared<DataTypeString>(); return std::make_shared<DataTypeString>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const ColumnPtr column_string = arguments[0].column; const ColumnPtr column_string = arguments[0].column;
const ColumnString * input = checkAndGetColumn<ColumnString>(column_string.get()); const ColumnString * input = checkAndGetColumn<ColumnString>(column_string.get());

View File

@ -613,7 +613,7 @@ class FunctionBinaryArithmetic : public IFunction
} }
/// Multiply aggregation state by integer constant: by merging it with itself specified number of times. /// Multiply aggregation state by integer constant: by merging it with itself specified number of times.
ColumnPtr executeAggregateMultiply(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const ColumnPtr executeAggregateMultiply(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const
{ {
ColumnsWithTypeAndName new_arguments = arguments; ColumnsWithTypeAndName new_arguments = arguments;
if (WhichDataType(new_arguments[1].type).isAggregateFunction()) if (WhichDataType(new_arguments[1].type).isAggregateFunction())
@ -680,7 +680,7 @@ class FunctionBinaryArithmetic : public IFunction
} }
/// Merge two aggregation states together. /// Merge two aggregation states together.
ColumnPtr executeAggregateAddition(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const ColumnPtr executeAggregateAddition(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const
{ {
const IColumn & lhs_column = *arguments[0].column; const IColumn & lhs_column = *arguments[0].column;
const IColumn & rhs_column = *arguments[1].column; const IColumn & rhs_column = *arguments[1].column;
@ -712,7 +712,7 @@ class FunctionBinaryArithmetic : public IFunction
return column_to; return column_to;
} }
ColumnPtr executeDateTimeIntervalPlusMinus(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, ColumnPtr executeDateTimeIntervalPlusMinus(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
size_t input_rows_count, const FunctionOverloadResolverPtr & function_builder) const size_t input_rows_count, const FunctionOverloadResolverPtr & function_builder) const
{ {
ColumnsWithTypeAndName new_arguments = arguments; ColumnsWithTypeAndName new_arguments = arguments;
@ -847,7 +847,7 @@ public:
return type_res; return type_res;
} }
ColumnPtr executeFixedString(ColumnsWithTypeAndName & arguments) const ColumnPtr executeFixedString(const ColumnsWithTypeAndName & arguments) const
{ {
using OpImpl = FixedStringOperationImpl<Op<UInt8, UInt8>>; using OpImpl = FixedStringOperationImpl<Op<UInt8, UInt8>>;
@ -923,7 +923,7 @@ public:
} }
template <typename A, typename B> template <typename A, typename B>
ColumnPtr executeNumeric(ColumnsWithTypeAndName & arguments, const A & left, const B & right) const ColumnPtr executeNumeric(const ColumnsWithTypeAndName & arguments, const A & left, const B & right) const
{ {
using LeftDataType = std::decay_t<decltype(left)>; using LeftDataType = std::decay_t<decltype(left)>;
using RightDataType = std::decay_t<decltype(right)>; using RightDataType = std::decay_t<decltype(right)>;
@ -1047,7 +1047,7 @@ public:
return nullptr; return nullptr;
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
/// Special case when multiply aggregate function state /// Special case when multiply aggregate function state
if (isAggregateMultiply(arguments[0].type, arguments[1].type)) if (isAggregateMultiply(arguments[0].type, arguments[1].type))
@ -1181,7 +1181,7 @@ public:
{ {
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
if (left.column && isColumnConst(*left.column) && arguments.size() == 1) if (left.column && isColumnConst(*left.column) && arguments.size() == 1)
{ {
@ -1206,11 +1206,7 @@ public:
bool hasInformationAboutMonotonicity() const override bool hasInformationAboutMonotonicity() const override
{ {
std::string_view name_ = Name::name; std::string_view name_ = Name::name;
if (name_ == "minus" || name_ == "plus" || name_ == "divide" || name_ == "intDiv") return (name_ == "minus" || name_ == "plus" || name_ == "divide" || name_ == "intDiv");
{
return true;
}
return false;
} }
Monotonicity getMonotonicityForRange(const IDataType &, const Field & left_point, const Field & right_point) const override Monotonicity getMonotonicityForRange(const IDataType &, const Field & left_point, const Field & right_point) const override

View File

@ -54,7 +54,7 @@ public:
return std::make_shared<DataTypeUInt8>(); return std::make_shared<DataTypeUInt8>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override
{ {
const auto * value_col = arguments.front().column.get(); const auto * value_col = arguments.front().column.get();
@ -75,7 +75,7 @@ public:
private: private:
template <typename T> template <typename T>
ColumnPtr execute( ColumnPtr execute(
ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type,
const IColumn * const value_col_untyped) const const IColumn * const value_col_untyped) const
{ {
if (const auto value_col = checkAndGetColumn<ColumnVector<T>>(value_col_untyped)) if (const auto value_col = checkAndGetColumn<ColumnVector<T>>(value_col_untyped))

View File

@ -96,7 +96,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; } ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type); WhichDataType which(from_type);

View File

@ -305,7 +305,7 @@ private:
template <typename FromDataType, typename ToDataType, typename Transform> template <typename FromDataType, typename ToDataType, typename Transform>
struct DateTimeAddIntervalImpl struct DateTimeAddIntervalImpl
{ {
static ColumnPtr execute(Transform transform, ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type) static ColumnPtr execute(Transform transform, const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type)
{ {
using FromValueType = typename FromDataType::FieldType; using FromValueType = typename FromDataType::FieldType;
using FromColumnType = typename FromDataType::ColumnType; using FromColumnType = typename FromDataType::ColumnType;
@ -463,7 +463,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {2}; } ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {2}; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type); WhichDataType which(from_type);

View File

@ -95,7 +95,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; } ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type); WhichDataType which(from_type);

View File

@ -34,7 +34,7 @@ public:
return std::make_shared<DataTypeString>(); return std::make_shared<DataTypeString>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName &, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName &, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
return result_type->createColumnConst( return result_type->createColumnConst(
input_rows_count, getFQDNOrHostName())->convertToFullColumnIfConst(); input_rows_count, getFQDNOrHostName())->convertToFullColumnIfConst();

View File

@ -17,7 +17,7 @@ namespace ErrorCodes
} }
template <bool or_null> template <bool or_null>
ColumnPtr ExecutableFunctionJoinGet<or_null>::execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) ColumnPtr ExecutableFunctionJoinGet<or_null>::execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const
{ {
ColumnsWithTypeAndName keys; ColumnsWithTypeAndName keys;
for (size_t i = 2; i < arguments.size(); ++i) for (size_t i = 2; i < arguments.size(); ++i)

View File

@ -24,7 +24,7 @@ public:
bool useDefaultImplementationForLowCardinalityColumns() const override { return true; } bool useDefaultImplementationForLowCardinalityColumns() const override { return true; }
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) override; ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override;
String getName() const override { return name; } String getName() const override { return name; }

View File

@ -204,7 +204,7 @@ private:
return nullptr; return nullptr;
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnWithTypeAndName & col_left = arguments[0]; const ColumnWithTypeAndName & col_left = arguments[0];
const ColumnWithTypeAndName & col_right = arguments[1]; const ColumnWithTypeAndName & col_right = arguments[1];

View File

@ -25,7 +25,7 @@ private:
return std::make_shared<DataTypeFloat64>(); return std::make_shared<DataTypeFloat64>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName &, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName &, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
return result_type->createColumnConst(input_rows_count, Impl::value); return result_type->createColumnConst(input_rows_count, Impl::value);
} }

View File

@ -148,7 +148,7 @@ private:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnWithTypeAndName & col = arguments[0]; const ColumnWithTypeAndName & col = arguments[0];
ColumnPtr res; ColumnPtr res;

View File

@ -46,7 +46,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const auto * in = arguments.front().column.get(); const auto * in = arguments.front().column.get();

View File

@ -63,7 +63,7 @@ public:
return std::make_shared<DataTypeUInt8>(); return std::make_shared<DataTypeUInt8>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const IColumn * haystack_column = arguments[0].column.get(); const IColumn * haystack_column = arguments[0].column.get();
const IColumn * needle_column = arguments[1].column.get(); const IColumn * needle_column = arguments[1].column.get();
@ -159,7 +159,7 @@ public:
#endif #endif
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
return selector.selectAndExecute(arguments, result_type, input_rows_count); return selector.selectAndExecute(arguments, result_type, input_rows_count);
} }

View File

@ -50,7 +50,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr column = arguments[0].column; const ColumnPtr column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))

View File

@ -52,7 +52,7 @@ public:
return std::make_shared<DataTypeString>(); return std::make_shared<DataTypeString>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr column_src = arguments[0].column; const ColumnPtr column_src = arguments[0].column;
const ColumnPtr column_needle = arguments[1].column; const ColumnPtr column_needle = arguments[1].column;

View File

@ -52,7 +52,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr column = arguments[0].column; const ColumnPtr column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))

View File

@ -154,7 +154,7 @@ public:
return result; return result;
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
ColumnPtr result_column; ColumnPtr result_column;
bool valid = castType(arguments[0].type.get(), [&](const auto & type) bool valid = castType(arguments[0].type.get(), [&](const auto & type)

View File

@ -65,7 +65,7 @@ public:
} }
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
using SourceColumnType = typename SourceDataType::ColumnType; using SourceColumnType = typename SourceDataType::ColumnType;
using ResultColumnType = typename ResultDataType::ColumnType; using ResultColumnType = typename ResultDataType::ColumnType;

View File

@ -178,7 +178,7 @@ private:
return std::make_shared<DataTypeString>(); return std::make_shared<DataTypeString>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
using namespace OpenSSLDetails; using namespace OpenSSLDetails;
@ -448,7 +448,7 @@ private:
return std::make_shared<DataTypeString>(); return std::make_shared<DataTypeString>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
using namespace OpenSSLDetails; using namespace OpenSSLDetails;

View File

@ -122,7 +122,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /* input_rows_count */) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /* input_rows_count */) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
const auto * array_type = typeid_cast<const DataTypeArray *>(from_type); const auto * array_type = typeid_cast<const DataTypeArray *>(from_type);
@ -146,7 +146,7 @@ public:
private: private:
template <typename T> template <typename T>
ColumnPtr executeBitmapData(DataTypes & argument_types, ColumnsWithTypeAndName & arguments) const ColumnPtr executeBitmapData(DataTypes & argument_types, const ColumnsWithTypeAndName & arguments) const
{ {
// input data // input data
const ColumnArray * array = typeid_cast<const ColumnArray *>(arguments[0].column.get()); const ColumnArray * array = typeid_cast<const ColumnArray *>(arguments[0].column.get());
@ -207,7 +207,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
// input data // input data
const auto & return_type = result_type; const auto & return_type = result_type;
@ -240,7 +240,7 @@ private:
template <typename T> template <typename T>
void executeIntType( void executeIntType(
ColumnsWithTypeAndName & arguments, size_t input_rows_count, IColumn & res_data_col, ColumnArray::Offsets & res_offsets) const ColumnsWithTypeAndName & arguments, size_t input_rows_count, IColumn & res_data_col, ColumnArray::Offsets & res_offsets)
const const
{ {
const ColumnAggregateFunction * column const ColumnAggregateFunction * column
@ -299,7 +299,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
@ -321,7 +321,7 @@ private:
using ToType = UInt64; using ToType = UInt64;
template <typename T> template <typename T>
ColumnPtr executeIntType(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const ColumnPtr executeIntType(const ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{ {
const IColumn * column_ptrs[3]; const IColumn * column_ptrs[3];
bool is_column_const[3]; bool is_column_const[3];
@ -417,7 +417,7 @@ public:
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
for (size_t i = 0; i < 2; ++i) for (size_t i = 0; i < 2; ++i)
{ {
auto array_type = typeid_cast<const DataTypeArray *>(arguments[i + 1].get()); const auto * array_type = typeid_cast<const DataTypeArray *>(arguments[i + 1].get());
String msg(i == 0 ? "Second" : "Third"); String msg(i == 0 ? "Second" : "Third");
msg += " argument for function " + getName() + " must be an UInt32 array but it has type " + arguments[i + 1]->getName() + "."; msg += " argument for function " + getName() + " must be an UInt32 array but it has type " + arguments[i + 1]->getName() + ".";
if (!array_type) if (!array_type)
@ -433,7 +433,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
@ -455,7 +455,7 @@ private:
using ToType = UInt64; using ToType = UInt64;
template <typename T> template <typename T>
ColumnPtr executeIntType(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const ColumnPtr executeIntType(const ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{ {
const IColumn * column_ptrs[3]; const IColumn * column_ptrs[3];
bool is_column_const[3]; bool is_column_const[3];
@ -565,7 +565,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
auto col_to = ColumnVector<ToType>::create(input_rows_count); auto col_to = ColumnVector<ToType>::create(input_rows_count);
typename ColumnVector<ToType>::Container & vec_to = col_to->getData(); typename ColumnVector<ToType>::Container & vec_to = col_to->getData();
@ -593,7 +593,7 @@ private:
template <typename T> template <typename T>
void executeIntType( void executeIntType(
ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const const ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const
{ {
const ColumnAggregateFunction * column const ColumnAggregateFunction * column
= typeid_cast<const ColumnAggregateFunction *>(arguments[0].column.get()); = typeid_cast<const ColumnAggregateFunction *>(arguments[0].column.get());
@ -735,7 +735,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
auto col_to = ColumnVector<UInt8>::create(input_rows_count); auto col_to = ColumnVector<UInt8>::create(input_rows_count);
typename ColumnVector<UInt8>::Container & vec_to = col_to->getData(); typename ColumnVector<UInt8>::Container & vec_to = col_to->getData();
@ -761,7 +761,7 @@ public:
private: private:
template <typename T> template <typename T>
void executeIntType( void executeIntType(
ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<UInt8>::Container & vec_to) const const ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<UInt8>::Container & vec_to) const
{ {
const IColumn * column_ptrs[2]; const IColumn * column_ptrs[2];
bool is_column_const[2]; bool is_column_const[2];
@ -832,7 +832,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
auto col_to = ColumnVector<ToType>::create(input_rows_count); auto col_to = ColumnVector<ToType>::create(input_rows_count);
typename ColumnVector<ToType>::Container & vec_to = col_to->getData(); typename ColumnVector<ToType>::Container & vec_to = col_to->getData();
@ -858,7 +858,7 @@ public:
private: private:
template <typename T> template <typename T>
void executeIntType( void executeIntType(
ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const const ColumnsWithTypeAndName & arguments, size_t input_rows_count, typename ColumnVector<ToType>::Container & vec_to) const
{ {
const ColumnAggregateFunction * column_ptrs[2]; const ColumnAggregateFunction * column_ptrs[2];
bool is_column_const[2]; bool is_column_const[2];
@ -967,7 +967,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type); const DataTypeAggregateFunction * aggr_type = typeid_cast<const DataTypeAggregateFunction *>(from_type);
@ -987,7 +987,7 @@ public:
private: private:
template <typename T> template <typename T>
ColumnPtr executeBitmapData(ColumnsWithTypeAndName & arguments, size_t input_rows_count) const ColumnPtr executeBitmapData(const ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{ {
const ColumnAggregateFunction * column_ptrs[2]; const ColumnAggregateFunction * column_ptrs[2];
bool is_column_const[2]; bool is_column_const[2];

View File

@ -88,7 +88,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const auto & col_type_name = arguments[0]; const auto & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column; const ColumnPtr & column = col_type_name.column;
@ -168,7 +168,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; } ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1, 2}; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const auto & col_type_name = arguments[0]; const auto & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column; const ColumnPtr & column = col_type_name.column;
@ -277,7 +277,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr & column = arguments[0].column; const ColumnPtr & column = arguments[0].column;
@ -339,7 +339,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr & column = arguments[0].column; const ColumnPtr & column = arguments[0].column;
@ -407,7 +407,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr & column = arguments[0].column; const ColumnPtr & column = arguments[0].column;
@ -460,7 +460,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const auto & col_type_name = arguments[0]; const auto & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column; const ColumnPtr & column = col_type_name.column;
@ -578,7 +578,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr & column = arguments[0].column; const ColumnPtr & column = arguments[0].column;
@ -688,7 +688,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr & column = arguments[0].column; const ColumnPtr & column = arguments[0].column;
@ -755,7 +755,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnWithTypeAndName & col_type_name = arguments[0]; const ColumnWithTypeAndName & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column; const ColumnPtr & column = col_type_name.column;
@ -857,7 +857,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnWithTypeAndName & col_type_name = arguments[0]; const ColumnWithTypeAndName & col_type_name = arguments[0];
const ColumnPtr & column = col_type_name.column; const ColumnPtr & column = col_type_name.column;
@ -1187,7 +1187,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const IColumn * column = arguments[0].column.get(); const IColumn * column = arguments[0].column.get();
ColumnPtr res_column; ColumnPtr res_column;
@ -1255,7 +1255,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const ColumnPtr & column = arguments[0].column; const ColumnPtr & column = arguments[0].column;
@ -1335,7 +1335,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
auto col_str = ColumnString::create(); auto col_str = ColumnString::create();
ColumnString::Chars & out_vec = col_str->getChars(); ColumnString::Chars & out_vec = col_str->getChars();
@ -1461,7 +1461,7 @@ public:
} }
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const IColumn * in_column = arguments[0].column.get(); const IColumn * in_column = arguments[0].column.get();
ColumnPtr out_column; ColumnPtr out_column;
@ -1599,7 +1599,7 @@ public:
} }
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const IColumn * column = arguments[0].column.get(); const IColumn * column = arguments[0].column.get();
ColumnPtr res_column; ColumnPtr res_column;
@ -1668,7 +1668,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const auto & col_type_name_ip = arguments[0]; const auto & col_type_name_ip = arguments[0];
const ColumnPtr & column_ip = col_type_name_ip.column; const ColumnPtr & column_ip = col_type_name_ip.column;
@ -1782,7 +1782,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const auto & col_type_name_ip = arguments[0]; const auto & col_type_name_ip = arguments[0];
const ColumnPtr & column_ip = col_type_name_ip.column; const ColumnPtr & column_ip = col_type_name_ip.column;

View File

@ -1136,7 +1136,7 @@ public:
return std::make_shared<DataTypeUInt8>(); return std::make_shared<DataTypeUInt8>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
const auto & col_with_type_and_name_left = arguments[0]; const auto & col_with_type_and_name_left = arguments[0];
const auto & col_with_type_and_name_right = arguments[1]; const auto & col_with_type_and_name_right = arguments[1];

View File

@ -65,7 +65,7 @@ public:
return {1}; return {1};
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
if (isColumnConst(*arguments[1].column)) if (isColumnConst(*arguments[1].column))
return executeConstBuckets(arguments); return executeConstBuckets(arguments);
@ -93,7 +93,7 @@ private:
return static_cast<BucketsType>(buckets); return static_cast<BucketsType>(buckets);
} }
ColumnPtr executeConstBuckets(ColumnsWithTypeAndName & arguments) const ColumnPtr executeConstBuckets(const ColumnsWithTypeAndName & arguments) const
{ {
Field buckets_field = (*arguments[1].column)[0]; Field buckets_field = (*arguments[1].column)[0];
BucketsType num_buckets; BucketsType num_buckets;

View File

@ -35,6 +35,7 @@
#include <Columns/ColumnsCommon.h> #include <Columns/ColumnsCommon.h>
#include <Common/FieldVisitors.h> #include <Common/FieldVisitors.h>
#include <Common/assert_cast.h> #include <Common/assert_cast.h>
#include <Common/quoteString.h>
#include <Functions/IFunctionAdaptors.h> #include <Functions/IFunctionAdaptors.h>
#include <Functions/FunctionsMiscellaneous.h> #include <Functions/FunctionsMiscellaneous.h>
#include <Functions/FunctionHelpers.h> #include <Functions/FunctionHelpers.h>
@ -102,7 +103,7 @@ struct ConvertImpl
template <typename Additions = void *> template <typename Additions = void *>
static ColumnPtr NO_SANITIZE_UNDEFINED execute( static ColumnPtr NO_SANITIZE_UNDEFINED execute(
ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t /*input_rows_count*/, const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t /*input_rows_count*/,
Additions additions [[maybe_unused]] = Additions()) Additions additions [[maybe_unused]] = Additions())
{ {
const ColumnWithTypeAndName & named_from = arguments[0]; const ColumnWithTypeAndName & named_from = arguments[0];
@ -153,6 +154,9 @@ struct ConvertImpl
{ {
if constexpr (std::is_same_v<FromFieldType, UInt128> || std::is_same_v<ToFieldType, UInt128>) if constexpr (std::is_same_v<FromFieldType, UInt128> || std::is_same_v<ToFieldType, UInt128>)
throw Exception("Unexpected UInt128 to big int conversion", ErrorCodes::NOT_IMPLEMENTED); throw Exception("Unexpected UInt128 to big int conversion", ErrorCodes::NOT_IMPLEMENTED);
/// If From Data is Nan or Inf, throw exception
else if (!isFinite(vec_from[i]))
throw Exception("Unexpected inf or nan to big int conversion", ErrorCodes::NOT_IMPLEMENTED);
else else
vec_to[i] = bigint_cast<ToFieldType>(vec_from[i]); vec_to[i] = bigint_cast<ToFieldType>(vec_from[i]);
} }
@ -442,7 +446,7 @@ struct FormatImpl<DataTypeDecimal<FieldType>>
template <typename FieldType, typename Name> template <typename FieldType, typename Name>
struct ConvertImpl<DataTypeEnum<FieldType>, DataTypeNumber<FieldType>, Name> struct ConvertImpl<DataTypeEnum<FieldType>, DataTypeNumber<FieldType>, Name>
{ {
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/)
{ {
return arguments[0].column; return arguments[0].column;
} }
@ -455,7 +459,7 @@ struct ConvertImpl<FromDataType, std::enable_if_t<!std::is_same_v<FromDataType,
using FromFieldType = typename FromDataType::FieldType; using FromFieldType = typename FromDataType::FieldType;
using ColVecType = std::conditional_t<IsDecimalNumber<FromFieldType>, ColumnDecimal<FromFieldType>, ColumnVector<FromFieldType>>; using ColVecType = std::conditional_t<IsDecimalNumber<FromFieldType>, ColumnDecimal<FromFieldType>, ColumnVector<FromFieldType>>;
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/)
{ {
const auto & col_with_type_and_name = arguments[0]; const auto & col_with_type_and_name = arguments[0];
const auto & type = static_cast<const FromDataType &>(*col_with_type_and_name.type); const auto & type = static_cast<const FromDataType &>(*col_with_type_and_name.type);
@ -509,7 +513,7 @@ struct ConvertImpl<FromDataType, std::enable_if_t<!std::is_same_v<FromDataType,
/// Generic conversion of any type to String. /// Generic conversion of any type to String.
struct ConvertImplGenericToString struct ConvertImplGenericToString
{ {
static ColumnPtr execute(ColumnsWithTypeAndName & arguments) static ColumnPtr execute(const ColumnsWithTypeAndName & arguments)
{ {
const auto & col_with_type_and_name = arguments[0]; const auto & col_with_type_and_name = arguments[0];
const IDataType & type = *col_with_type_and_name.type; const IDataType & type = *col_with_type_and_name.type;
@ -682,7 +686,7 @@ struct ConvertThroughParsing
} }
template <typename Additions = void *> template <typename Additions = void *>
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & res_type, size_t input_rows_count, static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr & res_type, size_t input_rows_count,
Additions additions [[maybe_unused]] = Additions()) Additions additions [[maybe_unused]] = Additions())
{ {
using ColVecTo = typename ToDataType::ColumnType; using ColVecTo = typename ToDataType::ColumnType;
@ -932,7 +936,7 @@ struct ConvertImpl<DataTypeString, DataTypeUInt32, NameToUnixTimestamp>
template <typename T, typename Name> template <typename T, typename Name>
struct ConvertImpl<std::enable_if_t<!T::is_parametric, T>, T, Name> struct ConvertImpl<std::enable_if_t<!T::is_parametric, T>, T, Name>
{ {
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/)
{ {
return arguments[0].column; return arguments[0].column;
} }
@ -945,7 +949,7 @@ struct ConvertImpl<std::enable_if_t<!T::is_parametric, T>, T, Name>
template <typename Name> template <typename Name>
struct ConvertImpl<DataTypeFixedString, DataTypeString, Name> struct ConvertImpl<DataTypeFixedString, DataTypeString, Name>
{ {
static ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) static ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/)
{ {
if (const ColumnFixedString * col_from = checkAndGetColumn<ColumnFixedString>(arguments[0].column.get())) if (const ColumnFixedString * col_from = checkAndGetColumn<ColumnFixedString>(arguments[0].column.get()))
{ {
@ -1141,7 +1145,7 @@ public:
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; } ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
bool canBeExecutedOnDefaultArguments() const override { return false; } bool canBeExecutedOnDefaultArguments() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
try try
{ {
@ -1186,7 +1190,7 @@ public:
} }
private: private:
ColumnPtr executeInternal(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const ColumnPtr executeInternal(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
{ {
if (arguments.empty()) if (arguments.empty())
throw Exception{"Function " + getName() + " expects at least 1 arguments", throw Exception{"Function " + getName() + " expects at least 1 arguments",
@ -1406,7 +1410,7 @@ public:
} }
template <typename ConvertToDataType> template <typename ConvertToDataType>
ColumnPtr executeInternal(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, UInt32 scale = 0) const ColumnPtr executeInternal(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, UInt32 scale = 0) const
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
@ -1424,7 +1428,7 @@ public:
return nullptr; return nullptr;
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
ColumnPtr result_column; ColumnPtr result_column;
@ -1874,20 +1878,37 @@ class ExecutableFunctionCast : public IExecutableFunctionImpl
public: public:
using WrapperType = std::function<ColumnPtr(ColumnsWithTypeAndName &, const DataTypePtr &, const ColumnNullable *, size_t)>; using WrapperType = std::function<ColumnPtr(ColumnsWithTypeAndName &, const DataTypePtr &, const ColumnNullable *, size_t)>;
explicit ExecutableFunctionCast(WrapperType && wrapper_function_, const char * name_) struct Diagnostic
: wrapper_function(std::move(wrapper_function_)), name(name_) {} {
std::string column_from;
std::string column_to;
};
explicit ExecutableFunctionCast(
WrapperType && wrapper_function_, const char * name_, std::optional<Diagnostic> diagnostic_)
: wrapper_function(std::move(wrapper_function_)), name(name_), diagnostic(std::move(diagnostic_)) {}
String getName() const override { return name; } String getName() const override { return name; }
protected: protected:
ColumnPtr execute(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) override ColumnPtr execute(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
/// drop second argument, pass others /// drop second argument, pass others
ColumnsWithTypeAndName new_arguments{arguments.front()}; ColumnsWithTypeAndName new_arguments{arguments.front()};
if (arguments.size() > 2) if (arguments.size() > 2)
new_arguments.insert(std::end(new_arguments), std::next(std::begin(arguments), 2), std::end(arguments)); new_arguments.insert(std::end(new_arguments), std::next(std::begin(arguments), 2), std::end(arguments));
return wrapper_function(new_arguments, result_type, nullptr, input_rows_count); try
{
return wrapper_function(new_arguments, result_type, nullptr, input_rows_count);
}
catch (Exception & e)
{
if (diagnostic)
e.addMessage("while converting source column " + backQuoteIfNeed(diagnostic->column_from) +
" to destination column " + backQuoteIfNeed(diagnostic->column_to));
throw;
}
} }
bool useDefaultImplementationForNulls() const override { return false; } bool useDefaultImplementationForNulls() const override { return false; }
@ -1898,6 +1919,7 @@ protected:
private: private:
WrapperType wrapper_function; WrapperType wrapper_function;
const char * name; const char * name;
std::optional<Diagnostic> diagnostic;
}; };
@ -1908,11 +1930,12 @@ class FunctionCast final : public IFunctionBaseImpl
public: public:
using WrapperType = std::function<ColumnPtr(ColumnsWithTypeAndName &, const DataTypePtr &, const ColumnNullable *, size_t)>; using WrapperType = std::function<ColumnPtr(ColumnsWithTypeAndName &, const DataTypePtr &, const ColumnNullable *, size_t)>;
using MonotonicityForRange = std::function<Monotonicity(const IDataType &, const Field &, const Field &)>; using MonotonicityForRange = std::function<Monotonicity(const IDataType &, const Field &, const Field &)>;
using Diagnostic = ExecutableFunctionCast::Diagnostic;
FunctionCast(const char * name_, MonotonicityForRange && monotonicity_for_range_ FunctionCast(const char * name_, MonotonicityForRange && monotonicity_for_range_
, const DataTypes & argument_types_, const DataTypePtr & return_type_) , const DataTypes & argument_types_, const DataTypePtr & return_type_, std::optional<Diagnostic> diagnostic_)
: name(name_), monotonicity_for_range(monotonicity_for_range_) : name(name_), monotonicity_for_range(monotonicity_for_range_)
, argument_types(argument_types_), return_type(return_type_) , argument_types(argument_types_), return_type(return_type_), diagnostic(std::move(diagnostic_))
{ {
} }
@ -1921,8 +1944,18 @@ public:
ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName & /*sample_columns*/) const override ExecutableFunctionImplPtr prepare(const ColumnsWithTypeAndName & /*sample_columns*/) const override
{ {
return std::make_unique<ExecutableFunctionCast>( try
prepareUnpackDictionaries(getArgumentTypes()[0], getResultType()), name); {
return std::make_unique<ExecutableFunctionCast>(
prepareUnpackDictionaries(getArgumentTypes()[0], getResultType()), name, diagnostic);
}
catch (Exception & e)
{
if (diagnostic)
e.addMessage("while converting source column " + backQuoteIfNeed(diagnostic->column_from) +
" to destination column " + backQuoteIfNeed(diagnostic->column_to));
throw;
}
} }
String getName() const override { return name; } String getName() const override { return name; }
@ -1948,6 +1981,8 @@ private:
DataTypes argument_types; DataTypes argument_types;
DataTypePtr return_type; DataTypePtr return_type;
std::optional<Diagnostic> diagnostic;
template <typename DataType> template <typename DataType>
WrapperType createWrapper(const DataTypePtr & from_type, const DataType * const, bool requested_result_is_nullable) const WrapperType createWrapper(const DataTypePtr & from_type, const DataType * const, bool requested_result_is_nullable) const
{ {
@ -2558,14 +2593,19 @@ class CastOverloadResolver : public IFunctionOverloadResolverImpl
{ {
public: public:
using MonotonicityForRange = FunctionCast::MonotonicityForRange; using MonotonicityForRange = FunctionCast::MonotonicityForRange;
using Diagnostic = FunctionCast::Diagnostic;
static constexpr auto name = "CAST"; static constexpr auto name = "CAST";
static FunctionOverloadResolverImplPtr create(const Context & context); static FunctionOverloadResolverImplPtr create(const Context & context);
static FunctionOverloadResolverImplPtr createImpl(bool keep_nullable) { return std::make_unique<CastOverloadResolver>(keep_nullable); } static FunctionOverloadResolverImplPtr createImpl(bool keep_nullable, std::optional<Diagnostic> diagnostic = {})
{
return std::make_unique<CastOverloadResolver>(keep_nullable, std::move(diagnostic));
}
explicit CastOverloadResolver(bool keep_nullable_)
: keep_nullable(keep_nullable_) explicit CastOverloadResolver(bool keep_nullable_, std::optional<Diagnostic> diagnostic_ = {})
: keep_nullable(keep_nullable_), diagnostic(std::move(diagnostic_))
{} {}
String getName() const override { return name; } String getName() const override { return name; }
@ -2584,7 +2624,7 @@ protected:
data_types[i] = arguments[i].type; data_types[i] = arguments[i].type;
auto monotonicity = getMonotonicityInformation(arguments.front().type, return_type.get()); auto monotonicity = getMonotonicityInformation(arguments.front().type, return_type.get());
return std::make_unique<FunctionCast>(name, std::move(monotonicity), data_types, return_type); return std::make_unique<FunctionCast>(name, std::move(monotonicity), data_types, return_type, diagnostic);
} }
DataTypePtr getReturnType(const ColumnsWithTypeAndName & arguments) const override DataTypePtr getReturnType(const ColumnsWithTypeAndName & arguments) const override
@ -2612,6 +2652,7 @@ protected:
private: private:
bool keep_nullable; bool keep_nullable;
std::optional<Diagnostic> diagnostic;
template <typename DataType> template <typename DataType>
static auto monotonicityForType(const DataType * const) static auto monotonicityForType(const DataType * const)

View File

@ -183,7 +183,7 @@ public:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
/// The dictionary key that defines the "point of view". /// The dictionary key that defines the "point of view".
std::string dict_key; std::string dict_key;
@ -279,7 +279,7 @@ public:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
/// The dictionary key that defines the "point of view". /// The dictionary key that defines the "point of view".
std::string dict_key; std::string dict_key;
@ -415,7 +415,7 @@ public:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
/// The dictionary key that defines the "point of view". /// The dictionary key that defines the "point of view".
std::string dict_key; std::string dict_key;
@ -620,7 +620,7 @@ public:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
RegionsNames::Language language = RegionsNames::Language::ru; RegionsNames::Language language = RegionsNames::Language::ru;

View File

@ -163,7 +163,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
/** Do not require existence of the dictionary if the function is called for empty columns. /** Do not require existence of the dictionary if the function is called for empty columns.
* This is needed to allow successful query analysis on a server, * This is needed to allow successful query analysis on a server,
@ -204,7 +204,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchSimple( ColumnPtr executeDispatchSimple(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -227,7 +227,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchComplex( ColumnPtr executeDispatchComplex(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -324,7 +324,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
if (input_rows_count == 0) if (input_rows_count == 0)
return result_type->createColumn(); return result_type->createColumn();
@ -359,7 +359,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatch( ColumnPtr executeDispatch(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -388,7 +388,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchComplex( ColumnPtr executeDispatchComplex(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -423,7 +423,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchRange( ColumnPtr executeDispatchRange(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -502,7 +502,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
if (input_rows_count == 0) if (input_rows_count == 0)
return result_type->createColumn(); return result_type->createColumn();
@ -621,7 +621,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchComplex( ColumnPtr executeDispatchComplex(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -839,7 +839,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
if (input_rows_count == 0) if (input_rows_count == 0)
return result_type->createColumn(); return result_type->createColumn();
@ -873,7 +873,7 @@ private:
} }
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatch(ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const ColumnPtr executeDispatch(const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -926,7 +926,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchComplex( ColumnPtr executeDispatchComplex(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -967,7 +967,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchRange( ColumnPtr executeDispatchRange(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -1094,7 +1094,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
if (input_rows_count == 0) if (input_rows_count == 0)
return result_type->createColumn(); return result_type->createColumn();
@ -1127,7 +1127,7 @@ private:
} }
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatch(ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const ColumnPtr executeDispatch(const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -1150,7 +1150,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatch( ColumnPtr executeDispatch(
ColumnsWithTypeAndName & arguments, const DictionaryType * dict, const ColumnsWithTypeAndName & arguments, const DictionaryType * dict,
const std::string & attr_name, const ColumnUInt64 * id_col) const const std::string & attr_name, const ColumnUInt64 * id_col) const
{ {
const auto * default_col_untyped = arguments[3].column.get(); const auto * default_col_untyped = arguments[3].column.get();
@ -1189,7 +1189,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatch( ColumnPtr executeDispatch(
ColumnsWithTypeAndName & arguments, const DictionaryType * dict, const ColumnsWithTypeAndName & arguments, const DictionaryType * dict,
const std::string & attr_name, const ColumnConst * id_col) const const std::string & attr_name, const ColumnConst * id_col) const
{ {
const auto * default_col_untyped = arguments[3].column.get(); const auto * default_col_untyped = arguments[3].column.get();
@ -1246,7 +1246,7 @@ private:
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatchComplex( ColumnPtr executeDispatchComplex(
ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -1472,7 +1472,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
return impl->executeImpl(arguments, result_type, input_rows_count); return impl->executeImpl(arguments, result_type, input_rows_count);
} }
@ -1613,7 +1613,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
return impl->executeImpl(arguments, result_type, input_rows_count); return impl->executeImpl(arguments, result_type, input_rows_count);
} }
@ -1661,7 +1661,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
if (input_rows_count == 0) if (input_rows_count == 0)
return result_type->createColumn(); return result_type->createColumn();
@ -1679,7 +1679,7 @@ private:
} }
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatch(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const ColumnPtr executeDispatch(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)
@ -1814,7 +1814,7 @@ private:
bool isDeterministic() const override { return false; } bool isDeterministic() const override { return false; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
if (input_rows_count == 0) if (input_rows_count == 0)
return result_type->createColumn(); return result_type->createColumn();
@ -1832,7 +1832,7 @@ private:
} }
template <typename DictionaryType> template <typename DictionaryType>
ColumnPtr executeDispatch(ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const ColumnPtr executeDispatch(const ColumnsWithTypeAndName & arguments, const std::shared_ptr<const IDictionaryBase> & dict_ptr) const
{ {
const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get()); const auto * dict = typeid_cast<const DictionaryType *>(dict_ptr.get());
if (!dict) if (!dict)

View File

@ -69,7 +69,7 @@ DataTypePtr FunctionModelEvaluate::getReturnTypeImpl(const ColumnsWithTypeAndNam
return type; return type;
} }
ColumnPtr FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const ColumnPtr FunctionModelEvaluate::executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const
{ {
const auto * name_col = checkAndGetColumnConst<ColumnString>(arguments[0].column.get()); const auto * name_col = checkAndGetColumnConst<ColumnString>(arguments[0].column.get());
if (!name_col) if (!name_col)
@ -85,7 +85,7 @@ ColumnPtr FunctionModelEvaluate::executeImpl(ColumnsWithTypeAndName & arguments,
column_ptrs.reserve(arguments.size()); column_ptrs.reserve(arguments.size());
for (auto arg : ext::range(1, arguments.size())) for (auto arg : ext::range(1, arguments.size()))
{ {
auto & column = arguments[arg].column; const auto & column = arguments[arg].column;
column_ptrs.push_back(column.get()); column_ptrs.push_back(column.get());
if (auto full_column = column->convertToFullColumnIfConst()) if (auto full_column = column->convertToFullColumnIfConst())
{ {

View File

@ -32,7 +32,7 @@ public:
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override; DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override;
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override; ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override;
private: private:
const ExternalModelsLoader & models_loader; const ExternalModelsLoader & models_loader;

View File

@ -555,7 +555,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
if (const ColumnString * col_from = checkAndGetColumn<ColumnString>(arguments[0].column.get())) if (const ColumnString * col_from = checkAndGetColumn<ColumnString>(arguments[0].column.get()))
{ {
@ -616,7 +616,7 @@ private:
using ToType = typename Impl::ReturnType; using ToType = typename Impl::ReturnType;
template <typename FromType> template <typename FromType>
ColumnPtr executeType(ColumnsWithTypeAndName & arguments) const ColumnPtr executeType(const ColumnsWithTypeAndName & arguments) const
{ {
using ColVecType = std::conditional_t<IsDecimalNumber<FromType>, ColumnDecimal<FromType>, ColumnVector<FromType>>; using ColVecType = std::conditional_t<IsDecimalNumber<FromType>, ColumnDecimal<FromType>, ColumnVector<FromType>>;
@ -659,7 +659,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const IDataType * from_type = arguments[0].type.get(); const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type); WhichDataType which(from_type);
@ -713,7 +713,7 @@ public:
#endif #endif
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
return selector.selectAndExecute(arguments, result_type, input_rows_count); return selector.selectAndExecute(arguments, result_type, input_rows_count);
} }
@ -1065,7 +1065,7 @@ public:
return std::make_shared<DataTypeNumber<ToType>>(); return std::make_shared<DataTypeNumber<ToType>>();
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
size_t rows = input_rows_count; size_t rows = input_rows_count;
auto col_to = ColumnVector<ToType>::create(rows); auto col_to = ColumnVector<ToType>::create(rows);
@ -1107,7 +1107,7 @@ public:
#endif #endif
} }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{ {
return selector.selectAndExecute(arguments, result_type, input_rows_count); return selector.selectAndExecute(arguments, result_type, input_rows_count);
} }
@ -1230,7 +1230,7 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; } ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
ColumnPtr executeImpl(ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override
{ {
const auto arg_count = arguments.size(); const auto arg_count = arguments.size();
@ -1243,7 +1243,7 @@ public:
} }
private: private:
ColumnPtr executeSingleArg(ColumnsWithTypeAndName & arguments) const ColumnPtr executeSingleArg(const ColumnsWithTypeAndName & arguments) const
{ {
const auto * col_untyped = arguments.front().column.get(); const auto * col_untyped = arguments.front().column.get();
@ -1273,7 +1273,7 @@ private:
" of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN}; " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN};
} }
ColumnPtr executeTwoArgs(ColumnsWithTypeAndName & arguments) const ColumnPtr executeTwoArgs(const ColumnsWithTypeAndName & arguments) const
{ {
const auto * level_col = arguments.back().column.get(); const auto * level_col = arguments.back().column.get();
if (!isColumnConst(*level_col)) if (!isColumnConst(*level_col))

View File

@ -10,7 +10,7 @@ namespace ErrorCodes
} }
std::vector<FunctionJSONHelpers::Move> FunctionJSONHelpers::prepareMoves(const char * function_name, ColumnsWithTypeAndName & columns, size_t first_index_argument, size_t num_index_arguments) std::vector<FunctionJSONHelpers::Move> FunctionJSONHelpers::prepareMoves(const char * function_name, const ColumnsWithTypeAndName & columns, size_t first_index_argument, size_t num_index_arguments)
{ {
std::vector<Move> moves; std::vector<Move> moves;
moves.reserve(num_index_arguments); moves.reserve(num_index_arguments);

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