Merge branch 'master' into tavplubix-patch-8

This commit is contained in:
Alexander Tokmakov 2023-08-01 13:30:13 +03:00 committed by GitHub
commit abb80d45f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
123 changed files with 485 additions and 336 deletions

View File

@ -161,5 +161,9 @@
"docker/test/sqllogic": { "docker/test/sqllogic": {
"name": "clickhouse/sqllogic-test", "name": "clickhouse/sqllogic-test",
"dependent": [] "dependent": []
},
"docker/test/integration/nginx_dav": {
"name": "clickhouse/nginx-dav",
"dependent": []
} }
} }

View File

@ -32,7 +32,7 @@ ENV MSAN_OPTIONS='abort_on_error=1 poison_in_dtor=1'
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen en_US.UTF-8 RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen en_US.UTF-8
ENV LC_ALL en_US.UTF-8 ENV LC_ALL en_US.UTF-8
ENV TZ=Europe/Moscow ENV TZ=Europe/Amsterdam
RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" > /etc/timezone RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" > /etc/timezone
CMD sleep 1 CMD sleep 1

View File

@ -32,7 +32,7 @@ RUN mkdir -p /tmp/clickhouse-odbc-tmp \
&& odbcinst -i -s -l -f /tmp/clickhouse-odbc-tmp/share/doc/clickhouse-odbc/config/odbc.ini.sample \ && odbcinst -i -s -l -f /tmp/clickhouse-odbc-tmp/share/doc/clickhouse-odbc/config/odbc.ini.sample \
&& rm -rf /tmp/clickhouse-odbc-tmp && rm -rf /tmp/clickhouse-odbc-tmp
ENV TZ=Europe/Moscow ENV TZ=Europe/Amsterdam
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV COMMIT_SHA='' ENV COMMIT_SHA=''

View File

@ -8,7 +8,7 @@ ARG apt_archive="http://archive.ubuntu.com"
RUN sed -i "s|http://archive.ubuntu.com|$apt_archive|g" /etc/apt/sources.list RUN sed -i "s|http://archive.ubuntu.com|$apt_archive|g" /etc/apt/sources.list
ENV LANG=C.UTF-8 ENV LANG=C.UTF-8
ENV TZ=Europe/Moscow ENV TZ=Europe/Amsterdam
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update \ RUN apt-get update \

View File

@ -0,0 +1,6 @@
FROM nginx:alpine-slim
COPY default.conf /etc/nginx/conf.d/
RUN mkdir /usr/share/nginx/files/ \
&& chown nginx: /usr/share/nginx/files/ -R

View File

@ -0,0 +1,25 @@
server {
listen 80;
#root /usr/share/nginx/test.com;
index index.html index.htm;
server_name test.com localhost;
location / {
expires max;
root /usr/share/nginx/files;
client_max_body_size 20m;
client_body_temp_path /usr/share/nginx/tmp;
dav_methods PUT; # Allowed methods, only PUT is necessary
create_full_put_path on; # nginx automatically creates nested directories
dav_access user:rw group:r all:r; # access permissions for files
limit_except GET {
allow all;
}
}
error_page 405 =200 $uri;
}

View File

@ -1,16 +1,15 @@
version: '2.3' version: '2.3'
services: services:
meili1: meili1:
image: getmeili/meilisearch:v0.27.0 image: getmeili/meilisearch:v0.27.0
restart: always restart: always
ports: ports:
- ${MEILI_EXTERNAL_PORT:-7700}:${MEILI_INTERNAL_PORT:-7700} - ${MEILI_EXTERNAL_PORT:-7700}:${MEILI_INTERNAL_PORT:-7700}
meili_secure: meili_secure:
image: getmeili/meilisearch:v0.27.0 image: getmeili/meilisearch:v0.27.0
restart: always restart: always
ports: ports:
- ${MEILI_SECURE_EXTERNAL_PORT:-7700}:${MEILI_SECURE_INTERNAL_PORT:-7700} - ${MEILI_SECURE_EXTERNAL_PORT:-7700}:${MEILI_SECURE_INTERNAL_PORT:-7700}
environment: environment:
MEILI_MASTER_KEY: "password" MEILI_MASTER_KEY: "password"

View File

@ -9,10 +9,10 @@ services:
DATADIR: /mysql/ DATADIR: /mysql/
expose: expose:
- ${MYSQL_PORT:-3306} - ${MYSQL_PORT:-3306}
command: --server_id=100 command: --server_id=100
--log-bin='mysql-bin-1.log' --log-bin='mysql-bin-1.log'
--default-time-zone='+3:00' --default-time-zone='+3:00'
--gtid-mode="ON" --gtid-mode="ON"
--enforce-gtid-consistency --enforce-gtid-consistency
--log-error-verbosity=3 --log-error-verbosity=3
--log-error=/mysql/error.log --log-error=/mysql/error.log
@ -21,4 +21,4 @@ services:
volumes: volumes:
- type: ${MYSQL_LOGS_FS:-tmpfs} - type: ${MYSQL_LOGS_FS:-tmpfs}
source: ${MYSQL_LOGS:-} source: ${MYSQL_LOGS:-}
target: /mysql/ target: /mysql/

View File

@ -9,9 +9,9 @@ services:
DATADIR: /mysql/ DATADIR: /mysql/
expose: expose:
- ${MYSQL8_PORT:-3306} - ${MYSQL8_PORT:-3306}
command: --server_id=100 --log-bin='mysql-bin-1.log' command: --server_id=100 --log-bin='mysql-bin-1.log'
--default_authentication_plugin='mysql_native_password' --default_authentication_plugin='mysql_native_password'
--default-time-zone='+3:00' --gtid-mode="ON" --default-time-zone='+3:00' --gtid-mode="ON"
--enforce-gtid-consistency --enforce-gtid-consistency
--log-error-verbosity=3 --log-error-verbosity=3
--log-error=/mysql/error.log --log-error=/mysql/error.log
@ -20,4 +20,4 @@ services:
volumes: volumes:
- type: ${MYSQL8_LOGS_FS:-tmpfs} - type: ${MYSQL8_LOGS_FS:-tmpfs}
source: ${MYSQL8_LOGS:-} source: ${MYSQL8_LOGS:-}
target: /mysql/ target: /mysql/

View File

@ -9,10 +9,10 @@ services:
DATADIR: /mysql/ DATADIR: /mysql/
expose: expose:
- ${MYSQL_CLUSTER_PORT:-3306} - ${MYSQL_CLUSTER_PORT:-3306}
command: --server_id=100 command: --server_id=100
--log-bin='mysql-bin-2.log' --log-bin='mysql-bin-2.log'
--default-time-zone='+3:00' --default-time-zone='+3:00'
--gtid-mode="ON" --gtid-mode="ON"
--enforce-gtid-consistency --enforce-gtid-consistency
--log-error-verbosity=3 --log-error-verbosity=3
--log-error=/mysql/2_error.log --log-error=/mysql/2_error.log
@ -31,10 +31,10 @@ services:
DATADIR: /mysql/ DATADIR: /mysql/
expose: expose:
- ${MYSQL_CLUSTER_PORT:-3306} - ${MYSQL_CLUSTER_PORT:-3306}
command: --server_id=100 command: --server_id=100
--log-bin='mysql-bin-3.log' --log-bin='mysql-bin-3.log'
--default-time-zone='+3:00' --default-time-zone='+3:00'
--gtid-mode="ON" --gtid-mode="ON"
--enforce-gtid-consistency --enforce-gtid-consistency
--log-error-verbosity=3 --log-error-verbosity=3
--log-error=/mysql/3_error.log --log-error=/mysql/3_error.log
@ -53,10 +53,10 @@ services:
DATADIR: /mysql/ DATADIR: /mysql/
expose: expose:
- ${MYSQL_CLUSTER_PORT:-3306} - ${MYSQL_CLUSTER_PORT:-3306}
command: --server_id=100 command: --server_id=100
--log-bin='mysql-bin-4.log' --log-bin='mysql-bin-4.log'
--default-time-zone='+3:00' --default-time-zone='+3:00'
--gtid-mode="ON" --gtid-mode="ON"
--enforce-gtid-consistency --enforce-gtid-consistency
--log-error-verbosity=3 --log-error-verbosity=3
--log-error=/mysql/4_error.log --log-error=/mysql/4_error.log
@ -65,4 +65,4 @@ services:
volumes: volumes:
- type: ${MYSQL_CLUSTER_LOGS_FS:-tmpfs} - type: ${MYSQL_CLUSTER_LOGS_FS:-tmpfs}
source: ${MYSQL_CLUSTER_LOGS:-} source: ${MYSQL_CLUSTER_LOGS:-}
target: /mysql/ target: /mysql/

View File

@ -5,7 +5,7 @@ services:
# Files will be put into /usr/share/nginx/files. # Files will be put into /usr/share/nginx/files.
nginx: nginx:
image: kssenii/nginx-test:1.1 image: clickhouse/nginx-dav:${DOCKER_NGINX_DAV_TAG:-latest}
restart: always restart: always
ports: ports:
- 80:80 - 80:80

View File

@ -12,9 +12,9 @@ services:
timeout: 5s timeout: 5s
retries: 5 retries: 5
networks: networks:
default: default:
aliases: aliases:
- postgre-sql.local - postgre-sql.local
environment: environment:
POSTGRES_HOST_AUTH_METHOD: "trust" POSTGRES_HOST_AUTH_METHOD: "trust"
POSTGRES_PASSWORD: mysecretpassword POSTGRES_PASSWORD: mysecretpassword

View File

@ -12,7 +12,7 @@ services:
command: ["zkServer.sh", "start-foreground"] command: ["zkServer.sh", "start-foreground"]
entrypoint: /zookeeper-ssl-entrypoint.sh entrypoint: /zookeeper-ssl-entrypoint.sh
volumes: volumes:
- type: bind - type: bind
source: /misc/zookeeper-ssl-entrypoint.sh source: /misc/zookeeper-ssl-entrypoint.sh
target: /zookeeper-ssl-entrypoint.sh target: /zookeeper-ssl-entrypoint.sh
- type: bind - type: bind
@ -37,7 +37,7 @@ services:
command: ["zkServer.sh", "start-foreground"] command: ["zkServer.sh", "start-foreground"]
entrypoint: /zookeeper-ssl-entrypoint.sh entrypoint: /zookeeper-ssl-entrypoint.sh
volumes: volumes:
- type: bind - type: bind
source: /misc/zookeeper-ssl-entrypoint.sh source: /misc/zookeeper-ssl-entrypoint.sh
target: /zookeeper-ssl-entrypoint.sh target: /zookeeper-ssl-entrypoint.sh
- type: bind - type: bind
@ -61,7 +61,7 @@ services:
command: ["zkServer.sh", "start-foreground"] command: ["zkServer.sh", "start-foreground"]
entrypoint: /zookeeper-ssl-entrypoint.sh entrypoint: /zookeeper-ssl-entrypoint.sh
volumes: volumes:
- type: bind - type: bind
source: /misc/zookeeper-ssl-entrypoint.sh source: /misc/zookeeper-ssl-entrypoint.sh
target: /zookeeper-ssl-entrypoint.sh target: /zookeeper-ssl-entrypoint.sh
- type: bind - type: bind

View File

@ -64,15 +64,16 @@ export CLICKHOUSE_ODBC_BRIDGE_BINARY_PATH=/clickhouse-odbc-bridge
export CLICKHOUSE_LIBRARY_BRIDGE_BINARY_PATH=/clickhouse-library-bridge export CLICKHOUSE_LIBRARY_BRIDGE_BINARY_PATH=/clickhouse-library-bridge
export DOCKER_BASE_TAG=${DOCKER_BASE_TAG:=latest} export DOCKER_BASE_TAG=${DOCKER_BASE_TAG:=latest}
export DOCKER_HELPER_TAG=${DOCKER_HELPER_TAG:=latest}
export DOCKER_MYSQL_GOLANG_CLIENT_TAG=${DOCKER_MYSQL_GOLANG_CLIENT_TAG:=latest}
export DOCKER_DOTNET_CLIENT_TAG=${DOCKER_DOTNET_CLIENT_TAG:=latest} export DOCKER_DOTNET_CLIENT_TAG=${DOCKER_DOTNET_CLIENT_TAG:=latest}
export DOCKER_HELPER_TAG=${DOCKER_HELPER_TAG:=latest}
export DOCKER_KERBERIZED_HADOOP_TAG=${DOCKER_KERBERIZED_HADOOP_TAG:=latest}
export DOCKER_KERBEROS_KDC_TAG=${DOCKER_KERBEROS_KDC_TAG:=latest}
export DOCKER_MYSQL_GOLANG_CLIENT_TAG=${DOCKER_MYSQL_GOLANG_CLIENT_TAG:=latest}
export DOCKER_MYSQL_JAVA_CLIENT_TAG=${DOCKER_MYSQL_JAVA_CLIENT_TAG:=latest} export DOCKER_MYSQL_JAVA_CLIENT_TAG=${DOCKER_MYSQL_JAVA_CLIENT_TAG:=latest}
export DOCKER_MYSQL_JS_CLIENT_TAG=${DOCKER_MYSQL_JS_CLIENT_TAG:=latest} export DOCKER_MYSQL_JS_CLIENT_TAG=${DOCKER_MYSQL_JS_CLIENT_TAG:=latest}
export DOCKER_MYSQL_PHP_CLIENT_TAG=${DOCKER_MYSQL_PHP_CLIENT_TAG:=latest} export DOCKER_MYSQL_PHP_CLIENT_TAG=${DOCKER_MYSQL_PHP_CLIENT_TAG:=latest}
export DOCKER_NGINX_DAV_TAG=${DOCKER_NGINX_DAV_TAG:=latest}
export DOCKER_POSTGRESQL_JAVA_CLIENT_TAG=${DOCKER_POSTGRESQL_JAVA_CLIENT_TAG:=latest} export DOCKER_POSTGRESQL_JAVA_CLIENT_TAG=${DOCKER_POSTGRESQL_JAVA_CLIENT_TAG:=latest}
export DOCKER_KERBEROS_KDC_TAG=${DOCKER_KERBEROS_KDC_TAG:=latest}
export DOCKER_KERBERIZED_HADOOP_TAG=${DOCKER_KERBERIZED_HADOOP_TAG:=latest}
cd /ClickHouse/tests/integration cd /ClickHouse/tests/integration
exec "$@" exec "$@"

View File

@ -11,7 +11,7 @@ ARG apt_archive="http://archive.ubuntu.com"
RUN sed -i "s|http://archive.ubuntu.com|$apt_archive|g" /etc/apt/sources.list RUN sed -i "s|http://archive.ubuntu.com|$apt_archive|g" /etc/apt/sources.list
ENV LANG=C.UTF-8 ENV LANG=C.UTF-8
ENV TZ=Europe/Moscow ENV TZ=Europe/Amsterdam
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update \ RUN apt-get update \

View File

@ -52,7 +52,7 @@ RUN mkdir -p /tmp/clickhouse-odbc-tmp \
&& odbcinst -i -s -l -f /tmp/clickhouse-odbc-tmp/share/doc/clickhouse-odbc/config/odbc.ini.sample \ && odbcinst -i -s -l -f /tmp/clickhouse-odbc-tmp/share/doc/clickhouse-odbc/config/odbc.ini.sample \
&& rm -rf /tmp/clickhouse-odbc-tmp && rm -rf /tmp/clickhouse-odbc-tmp
ENV TZ=Europe/Moscow ENV TZ=Europe/Amsterdam
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV NUM_TRIES=1 ENV NUM_TRIES=1

View File

@ -233,4 +233,10 @@ rowNumberInAllBlocks()
LIMIT 1" < /test_output/test_results.tsv > /test_output/check_status.tsv || echo "failure\tCannot parse test_results.tsv" > /test_output/check_status.tsv LIMIT 1" < /test_output/test_results.tsv > /test_output/check_status.tsv || echo "failure\tCannot parse test_results.tsv" > /test_output/check_status.tsv
[ -s /test_output/check_status.tsv ] || echo -e "success\tNo errors found" > /test_output/check_status.tsv [ -s /test_output/check_status.tsv ] || echo -e "success\tNo errors found" > /test_output/check_status.tsv
# But OOMs in stress test are allowed
if rg 'OOM in dmesg|Signal 9' /test_output/check_status.tsv
then
sed -i 's/failure/success/' /test_output/check_status.tsv
fi
collect_core_dumps collect_core_dumps

View File

@ -231,4 +231,10 @@ rowNumberInAllBlocks()
LIMIT 1" < /test_output/test_results.tsv > /test_output/check_status.tsv || echo "failure\tCannot parse test_results.tsv" > /test_output/check_status.tsv LIMIT 1" < /test_output/test_results.tsv > /test_output/check_status.tsv || echo "failure\tCannot parse test_results.tsv" > /test_output/check_status.tsv
[ -s /test_output/check_status.tsv ] || echo -e "success\tNo errors found" > /test_output/check_status.tsv [ -s /test_output/check_status.tsv ] || echo -e "success\tNo errors found" > /test_output/check_status.tsv
# But OOMs in stress test are allowed
if rg 'OOM in dmesg|Signal 9' /test_output/check_status.tsv
then
sed -i 's/failure/success/' /test_output/check_status.tsv
fi
collect_core_dumps collect_core_dumps

View File

@ -84,6 +84,7 @@ The BACKUP and RESTORE statements take a list of DATABASE and TABLE names, a des
- `password` for the file on disk - `password` for the file on disk
- `base_backup`: the destination of the previous backup of this source. For example, `Disk('backups', '1.zip')` - `base_backup`: the destination of the previous backup of this source. For example, `Disk('backups', '1.zip')`
- `structure_only`: if enabled, allows to only backup or restore the CREATE statements without the data of tables - `structure_only`: if enabled, allows to only backup or restore the CREATE statements without the data of tables
- `s3_storage_class`: the storage class used for S3 backup. For example, `STANDARD`
### Usage examples ### Usage examples

View File

@ -140,8 +140,8 @@ Time shifts for multiple days. Some pacific islands changed their timezone offse
- [Type conversion functions](../../sql-reference/functions/type-conversion-functions.md) - [Type conversion functions](../../sql-reference/functions/type-conversion-functions.md)
- [Functions for working with dates and times](../../sql-reference/functions/date-time-functions.md) - [Functions for working with dates and times](../../sql-reference/functions/date-time-functions.md)
- [Functions for working with arrays](../../sql-reference/functions/array-functions.md) - [Functions for working with arrays](../../sql-reference/functions/array-functions.md)
- [The `date_time_input_format` setting](../../operations/settings/settings.md#settings-date_time_input_format) - [The `date_time_input_format` setting](../../operations/settings/settings-formats.md#settings-date_time_input_format)
- [The `date_time_output_format` setting](../../operations/settings/settings.md#settings-date_time_output_format) - [The `date_time_output_format` setting](../../operations/settings/settings-formats.md#settings-date_time_output_format)
- [The `timezone` server configuration parameter](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) - [The `timezone` server configuration parameter](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone)
- [The `session_timezone` setting](../../operations/settings/settings.md#session_timezone) - [The `session_timezone` setting](../../operations/settings/settings.md#session_timezone)
- [Operators for working with dates and times](../../sql-reference/operators/index.md#operators-datetime) - [Operators for working with dates and times](../../sql-reference/operators/index.md#operators-datetime)

View File

@ -30,6 +30,7 @@ public:
String compression_method; String compression_method;
int compression_level = -1; int compression_level = -1;
String password; String password;
String s3_storage_class;
ContextPtr context; ContextPtr context;
bool is_internal_backup = false; bool is_internal_backup = false;
std::shared_ptr<IBackupCoordination> backup_coordination; std::shared_ptr<IBackupCoordination> backup_coordination;

View File

@ -88,7 +88,7 @@ namespace
request.SetMaxKeys(1); request.SetMaxKeys(1);
auto outcome = client.ListObjects(request); auto outcome = client.ListObjects(request);
if (!outcome.IsSuccess()) if (!outcome.IsSuccess())
throw Exception::createDeprecated(outcome.GetError().GetMessage(), ErrorCodes::S3_ERROR); throw S3Exception(outcome.GetError().GetMessage(), outcome.GetError().GetErrorType());
return outcome.GetResult().GetContents(); return outcome.GetResult().GetContents();
} }
@ -178,7 +178,7 @@ void BackupReaderS3::copyFileToDisk(const String & path_in_backup, size_t file_s
BackupWriterS3::BackupWriterS3( BackupWriterS3::BackupWriterS3(
const S3::URI & s3_uri_, const String & access_key_id_, const String & secret_access_key_, bool allow_s3_native_copy, const ContextPtr & context_) const S3::URI & s3_uri_, const String & access_key_id_, const String & secret_access_key_, bool allow_s3_native_copy, const String & storage_class_name, const ContextPtr & context_)
: BackupWriterDefault(&Poco::Logger::get("BackupWriterS3"), context_) : BackupWriterDefault(&Poco::Logger::get("BackupWriterS3"), context_)
, s3_uri(s3_uri_) , s3_uri(s3_uri_)
, client(makeS3Client(s3_uri_, access_key_id_, secret_access_key_, context_)) , client(makeS3Client(s3_uri_, access_key_id_, secret_access_key_, context_))
@ -188,6 +188,7 @@ BackupWriterS3::BackupWriterS3(
request_settings.updateFromSettings(context_->getSettingsRef()); request_settings.updateFromSettings(context_->getSettingsRef());
request_settings.max_single_read_retries = context_->getSettingsRef().s3_max_single_read_retries; // FIXME: Avoid taking value for endpoint request_settings.max_single_read_retries = context_->getSettingsRef().s3_max_single_read_retries; // FIXME: Avoid taking value for endpoint
request_settings.allow_native_copy = allow_s3_native_copy; request_settings.allow_native_copy = allow_s3_native_copy;
request_settings.setStorageClassName(storage_class_name);
} }
void BackupWriterS3::copyFileFromDisk(const String & path_in_backup, DiskPtr src_disk, const String & src_path, void BackupWriterS3::copyFileFromDisk(const String & path_in_backup, DiskPtr src_disk, const String & src_path,
@ -271,7 +272,7 @@ void BackupWriterS3::removeFile(const String & file_name)
request.SetKey(fs::path(s3_uri.key) / file_name); request.SetKey(fs::path(s3_uri.key) / file_name);
auto outcome = client->DeleteObject(request); auto outcome = client->DeleteObject(request);
if (!outcome.IsSuccess() && !isNotFoundError(outcome.GetError().GetErrorType())) if (!outcome.IsSuccess() && !isNotFoundError(outcome.GetError().GetErrorType()))
throw Exception::createDeprecated(outcome.GetError().GetMessage(), ErrorCodes::S3_ERROR); throw S3Exception(outcome.GetError().GetMessage(), outcome.GetError().GetErrorType());
} }
void BackupWriterS3::removeFiles(const Strings & file_names) void BackupWriterS3::removeFiles(const Strings & file_names)
@ -329,7 +330,7 @@ void BackupWriterS3::removeFilesBatch(const Strings & file_names)
auto outcome = client->DeleteObjects(request); auto outcome = client->DeleteObjects(request);
if (!outcome.IsSuccess() && !isNotFoundError(outcome.GetError().GetErrorType())) if (!outcome.IsSuccess() && !isNotFoundError(outcome.GetError().GetErrorType()))
throw Exception::createDeprecated(outcome.GetError().GetMessage(), ErrorCodes::S3_ERROR); throw S3Exception(outcome.GetError().GetMessage(), outcome.GetError().GetErrorType());
} }
} }

View File

@ -38,7 +38,7 @@ private:
class BackupWriterS3 : public BackupWriterDefault class BackupWriterS3 : public BackupWriterDefault
{ {
public: public:
BackupWriterS3(const S3::URI & s3_uri_, const String & access_key_id_, const String & secret_access_key_, bool allow_s3_native_copy, const ContextPtr & context_); BackupWriterS3(const S3::URI & s3_uri_, const String & access_key_id_, const String & secret_access_key_, bool allow_s3_native_copy, const String & storage_class_name, const ContextPtr & context_);
~BackupWriterS3() override; ~BackupWriterS3() override;
bool fileExists(const String & file_name) override; bool fileExists(const String & file_name) override;

View File

@ -21,6 +21,7 @@ namespace ErrorCodes
M(String, id) \ M(String, id) \
M(String, compression_method) \ M(String, compression_method) \
M(String, password) \ M(String, password) \
M(String, s3_storage_class) \
M(Bool, structure_only) \ M(Bool, structure_only) \
M(Bool, async) \ M(Bool, async) \
M(Bool, decrypt_files_from_encrypted_disks) \ M(Bool, decrypt_files_from_encrypted_disks) \

View File

@ -25,6 +25,9 @@ struct BackupSettings
/// Password used to encrypt the backup. /// Password used to encrypt the backup.
String password; String password;
/// S3 storage class.
String s3_storage_class = "";
/// If this is set to true then only create queries will be written to backup, /// If this is set to true then only create queries will be written to backup,
/// without the data of tables. /// without the data of tables.
bool structure_only = false; bool structure_only = false;

View File

@ -344,6 +344,7 @@ void BackupsWorker::doBackup(
backup_create_params.compression_method = backup_settings.compression_method; backup_create_params.compression_method = backup_settings.compression_method;
backup_create_params.compression_level = backup_settings.compression_level; backup_create_params.compression_level = backup_settings.compression_level;
backup_create_params.password = backup_settings.password; backup_create_params.password = backup_settings.password;
backup_create_params.s3_storage_class = backup_settings.s3_storage_class;
backup_create_params.is_internal_backup = backup_settings.internal; backup_create_params.is_internal_backup = backup_settings.internal;
backup_create_params.backup_coordination = backup_coordination; backup_create_params.backup_coordination = backup_coordination;
backup_create_params.backup_uuid = backup_settings.backup_uuid; backup_create_params.backup_uuid = backup_settings.backup_uuid;

View File

@ -112,7 +112,7 @@ void registerBackupEngineS3(BackupFactory & factory)
} }
else else
{ {
auto writer = std::make_shared<BackupWriterS3>(S3::URI{s3_uri}, access_key_id, secret_access_key, params.allow_s3_native_copy, params.context); auto writer = std::make_shared<BackupWriterS3>(S3::URI{s3_uri}, access_key_id, secret_access_key, params.allow_s3_native_copy, params.s3_storage_class, params.context);
return std::make_unique<BackupImpl>( return std::make_unique<BackupImpl>(
backup_name_for_logging, backup_name_for_logging,
archive_params, archive_params,

View File

@ -153,7 +153,10 @@ Pool::Entry Pool::get(uint64_t wait_timeout)
for (auto & connection : connections) for (auto & connection : connections)
{ {
if (connection->ref_count == 0) if (connection->ref_count == 0)
{
logger.test("Found free connection in pool, returning it to the caller");
return Entry(connection, this); return Entry(connection, this);
}
} }
logger.trace("(%s): Trying to allocate a new connection.", getDescription()); logger.trace("(%s): Trying to allocate a new connection.", getDescription());

View File

@ -26,7 +26,7 @@ namespace mysqlxx
* *
* void thread() * void thread()
* { * {
* mysqlxx::Pool::Entry connection = pool.Get(); * mysqlxx::Pool::Entry connection = pool.Get();
* std::string s = connection->query("SELECT 'Hello, world!' AS world").use().fetch()["world"].getString(); * std::string s = connection->query("SELECT 'Hello, world!' AS world").use().fetch()["world"].getString();
* } * }
* TODO: simplify with PoolBase. * TODO: simplify with PoolBase.

View File

@ -320,8 +320,6 @@ bool KeeperDispatcher::putRequest(const Coordination::ZooKeeperRequestPtr & requ
request_info.time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); request_info.time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
request_info.session_id = session_id; request_info.session_id = session_id;
std::lock_guard lock(push_request_mutex);
if (shutdown_called) if (shutdown_called)
return false; return false;
@ -423,13 +421,10 @@ void KeeperDispatcher::shutdown()
try try
{ {
{ {
std::lock_guard lock(push_request_mutex); if (shutdown_called.exchange(true))
if (shutdown_called)
return; return;
LOG_DEBUG(log, "Shutting down storage dispatcher"); LOG_DEBUG(log, "Shutting down storage dispatcher");
shutdown_called = true;
if (session_cleaner_thread.joinable()) if (session_cleaner_thread.joinable())
session_cleaner_thread.join(); session_cleaner_thread.join();
@ -582,12 +577,9 @@ void KeeperDispatcher::sessionCleanerTask()
.time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(), .time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(),
.request = std::move(request), .request = std::move(request),
}; };
{ if (!requests_queue->push(std::move(request_info)))
std::lock_guard lock(push_request_mutex); LOG_INFO(log, "Cannot push close request to queue while cleaning outdated sessions");
if (!requests_queue->push(std::move(request_info))) CurrentMetrics::add(CurrentMetrics::KeeperOutstandingRequets);
LOG_INFO(log, "Cannot push close request to queue while cleaning outdated sessions");
CurrentMetrics::add(CurrentMetrics::KeeperOutstandingRequets);
}
/// Remove session from registered sessions /// Remove session from registered sessions
finishSession(dead_session); finishSession(dead_session);
@ -607,6 +599,10 @@ void KeeperDispatcher::sessionCleanerTask()
void KeeperDispatcher::finishSession(int64_t session_id) void KeeperDispatcher::finishSession(int64_t session_id)
{ {
/// shutdown() method will cleanup sessions if needed
if (shutdown_called)
return;
{ {
std::lock_guard lock(session_to_response_callback_mutex); std::lock_guard lock(session_to_response_callback_mutex);
auto session_it = session_to_response_callback.find(session_id); auto session_it = session_to_response_callback.find(session_id);
@ -698,12 +694,9 @@ int64_t KeeperDispatcher::getSessionID(int64_t session_timeout_ms)
} }
/// Push new session request to queue /// Push new session request to queue
{ if (!requests_queue->tryPush(std::move(request_info), session_timeout_ms))
std::lock_guard lock(push_request_mutex); throw Exception(ErrorCodes::TIMEOUT_EXCEEDED, "Cannot push session id request to queue within session timeout");
if (!requests_queue->tryPush(std::move(request_info), session_timeout_ms)) CurrentMetrics::add(CurrentMetrics::KeeperOutstandingRequets);
throw Exception(ErrorCodes::TIMEOUT_EXCEEDED, "Cannot push session id request to queue within session timeout");
CurrentMetrics::add(CurrentMetrics::KeeperOutstandingRequets);
}
if (future.wait_for(std::chrono::milliseconds(session_timeout_ms)) != std::future_status::ready) if (future.wait_for(std::chrono::milliseconds(session_timeout_ms)) != std::future_status::ready)
throw Exception(ErrorCodes::TIMEOUT_EXCEEDED, "Cannot receive session id within session timeout"); throw Exception(ErrorCodes::TIMEOUT_EXCEEDED, "Cannot receive session id within session timeout");
@ -871,10 +864,7 @@ uint64_t KeeperDispatcher::getSnapDirSize() const
Keeper4LWInfo KeeperDispatcher::getKeeper4LWInfo() const Keeper4LWInfo KeeperDispatcher::getKeeper4LWInfo() const
{ {
Keeper4LWInfo result = server->getPartiallyFilled4LWInfo(); Keeper4LWInfo result = server->getPartiallyFilled4LWInfo();
{ result.outstanding_requests_count = requests_queue->size();
std::lock_guard lock(push_request_mutex);
result.outstanding_requests_count = requests_queue->size();
}
{ {
std::lock_guard lock(session_to_response_callback_mutex); std::lock_guard lock(session_to_response_callback_mutex);
result.alive_connections_count = session_to_response_callback.size(); result.alive_connections_count = session_to_response_callback.size();

View File

@ -27,8 +27,6 @@ using ZooKeeperResponseCallback = std::function<void(const Coordination::ZooKeep
class KeeperDispatcher class KeeperDispatcher
{ {
private: private:
mutable std::mutex push_request_mutex;
using RequestsQueue = ConcurrentBoundedQueue<KeeperStorage::RequestForSession>; using RequestsQueue = ConcurrentBoundedQueue<KeeperStorage::RequestForSession>;
using SessionToResponseCallback = std::unordered_map<int64_t, ZooKeeperResponseCallback>; using SessionToResponseCallback = std::unordered_map<int64_t, ZooKeeperResponseCallback>;
using ClusterUpdateQueue = ConcurrentBoundedQueue<ClusterUpdateAction>; using ClusterUpdateQueue = ConcurrentBoundedQueue<ClusterUpdateAction>;

View File

@ -794,8 +794,14 @@ bool KeeperServer::applyConfigUpdate(const ClusterUpdateAction & action)
std::lock_guard _{server_write_mutex}; std::lock_guard _{server_write_mutex};
if (const auto * add = std::get_if<AddRaftServer>(&action)) if (const auto * add = std::get_if<AddRaftServer>(&action))
return raft_instance->get_srv_config(add->id) != nullptr {
|| raft_instance->add_srv(static_cast<nuraft::srv_config>(*add))->get_accepted(); if (raft_instance->get_srv_config(add->id) != nullptr)
return true;
auto resp = raft_instance->add_srv(static_cast<nuraft::srv_config>(*add));
resp->get();
return resp->get_accepted();
}
else if (const auto * remove = std::get_if<RemoveRaftServer>(&action)) else if (const auto * remove = std::get_if<RemoveRaftServer>(&action))
{ {
if (remove->id == raft_instance->get_leader()) if (remove->id == raft_instance->get_leader())
@ -807,8 +813,12 @@ bool KeeperServer::applyConfigUpdate(const ClusterUpdateAction & action)
return false; return false;
} }
return raft_instance->get_srv_config(remove->id) == nullptr if (raft_instance->get_srv_config(remove->id) == nullptr)
|| raft_instance->remove_srv(remove->id)->get_accepted(); return true;
auto resp = raft_instance->remove_srv(remove->id);
resp->get();
return resp->get_accepted();
} }
else if (const auto * update = std::get_if<UpdateRaftServerPriority>(&action)) else if (const auto * update = std::get_if<UpdateRaftServerPriority>(&action))
{ {

View File

@ -65,6 +65,7 @@ void DatabaseMaterializedMySQL::setException(const std::exception_ptr & exceptio
void DatabaseMaterializedMySQL::startupTables(ThreadPool & thread_pool, LoadingStrictnessLevel mode) void DatabaseMaterializedMySQL::startupTables(ThreadPool & thread_pool, LoadingStrictnessLevel mode)
{ {
LOG_TRACE(log, "Starting MaterializeMySQL tables");
DatabaseAtomic::startupTables(thread_pool, mode); DatabaseAtomic::startupTables(thread_pool, mode);
if (mode < LoadingStrictnessLevel::FORCE_ATTACH) if (mode < LoadingStrictnessLevel::FORCE_ATTACH)
@ -122,6 +123,7 @@ void DatabaseMaterializedMySQL::alterTable(ContextPtr context_, const StorageID
void DatabaseMaterializedMySQL::drop(ContextPtr context_) void DatabaseMaterializedMySQL::drop(ContextPtr context_)
{ {
LOG_TRACE(log, "Dropping MaterializeMySQL database");
/// Remove metadata info /// Remove metadata info
fs::path metadata(getMetadataPath() + "/.metadata"); fs::path metadata(getMetadataPath() + "/.metadata");

View File

@ -11,6 +11,7 @@
#include <Databases/DatabaseAtomic.h> #include <Databases/DatabaseAtomic.h>
#include <Databases/MySQL/MaterializedMySQLSettings.h> #include <Databases/MySQL/MaterializedMySQLSettings.h>
#include <Databases/MySQL/MaterializedMySQLSyncThread.h> #include <Databases/MySQL/MaterializedMySQLSyncThread.h>
#include <Common/logger_useful.h>
namespace DB namespace DB
{ {

View File

@ -1,3 +1,4 @@
#include "Common/logger_useful.h"
#include "config.h" #include "config.h"
#if USE_MYSQL #if USE_MYSQL
@ -499,7 +500,10 @@ bool MaterializedMySQLSyncThread::prepareSynchronized(MaterializeMetadata & meta
{ {
throw; throw;
} }
catch (const mysqlxx::ConnectionFailed &) {} catch (const mysqlxx::ConnectionFailed & ex)
{
LOG_TRACE(log, "Connection to MySQL failed {}", ex.displayText());
}
catch (const mysqlxx::BadQuery & e) catch (const mysqlxx::BadQuery & e)
{ {
// Lost connection to MySQL server during query // Lost connection to MySQL server during query

View File

@ -135,7 +135,7 @@ private:
return result; return result;
} }
throw Exception(ErrorCodes::S3_ERROR, "Could not list objects in bucket {} with prefix {}, S3 exception: {}, message: {}", throw S3Exception(outcome.GetError().GetErrorType(), "Could not list objects in bucket {} with prefix {}, S3 exception: {}, message: {}",
quoteString(request.GetBucket()), quoteString(request.GetPrefix()), quoteString(request.GetBucket()), quoteString(request.GetPrefix()),
backQuote(outcome.GetError().GetExceptionName()), quoteString(outcome.GetError().GetMessage())); backQuote(outcome.GetError().GetExceptionName()), quoteString(outcome.GetError().GetMessage()));
} }

View File

@ -31,7 +31,7 @@ namespace ErrorCodes
message.empty() ? "" : ": " + message); message.empty() ? "" : ": " + message);
} }
Poco::AutoPtr<Poco::XML::Document> getDiskConfigurationFromASTImpl(const std::string & root_name, const ASTs & disk_args, ContextPtr context) Poco::AutoPtr<Poco::XML::Document> getDiskConfigurationFromASTImpl(const ASTs & disk_args, ContextPtr context)
{ {
if (disk_args.empty()) if (disk_args.empty())
throwBadConfiguration("expected non-empty list of arguments"); throwBadConfiguration("expected non-empty list of arguments");
@ -39,8 +39,6 @@ Poco::AutoPtr<Poco::XML::Document> getDiskConfigurationFromASTImpl(const std::st
Poco::AutoPtr<Poco::XML::Document> xml_document(new Poco::XML::Document()); Poco::AutoPtr<Poco::XML::Document> xml_document(new Poco::XML::Document());
Poco::AutoPtr<Poco::XML::Element> root(xml_document->createElement("disk")); Poco::AutoPtr<Poco::XML::Element> root(xml_document->createElement("disk"));
xml_document->appendChild(root); xml_document->appendChild(root);
Poco::AutoPtr<Poco::XML::Element> disk_configuration(xml_document->createElement(root_name));
root->appendChild(disk_configuration);
for (const auto & arg : disk_args) for (const auto & arg : disk_args)
{ {
@ -62,7 +60,7 @@ Poco::AutoPtr<Poco::XML::Document> getDiskConfigurationFromASTImpl(const std::st
const std::string & key = key_identifier->name(); const std::string & key = key_identifier->name();
Poco::AutoPtr<Poco::XML::Element> key_element(xml_document->createElement(key)); Poco::AutoPtr<Poco::XML::Element> key_element(xml_document->createElement(key));
disk_configuration->appendChild(key_element); root->appendChild(key_element);
if (!function_args[1]->as<ASTLiteral>() && !function_args[1]->as<ASTIdentifier>()) if (!function_args[1]->as<ASTLiteral>() && !function_args[1]->as<ASTIdentifier>())
throwBadConfiguration("expected values to be literals or identifiers"); throwBadConfiguration("expected values to be literals or identifiers");
@ -75,9 +73,9 @@ Poco::AutoPtr<Poco::XML::Document> getDiskConfigurationFromASTImpl(const std::st
return xml_document; return xml_document;
} }
DiskConfigurationPtr getDiskConfigurationFromAST(const std::string & root_name, const ASTs & disk_args, ContextPtr context) DiskConfigurationPtr getDiskConfigurationFromAST(const ASTs & disk_args, ContextPtr context)
{ {
auto xml_document = getDiskConfigurationFromASTImpl(root_name, disk_args, context); auto xml_document = getDiskConfigurationFromASTImpl(disk_args, context);
Poco::AutoPtr<Poco::Util::XMLConfiguration> conf(new Poco::Util::XMLConfiguration()); Poco::AutoPtr<Poco::Util::XMLConfiguration> conf(new Poco::Util::XMLConfiguration());
conf->load(xml_document); conf->load(xml_document);
return conf; return conf;

View File

@ -14,19 +14,19 @@ using DiskConfigurationPtr = Poco::AutoPtr<Poco::Util::AbstractConfiguration>;
/** /**
* Transform a list of pairs ( key1=value1, key2=value2, ... ), where keys and values are ASTLiteral or ASTIdentifier * Transform a list of pairs ( key1=value1, key2=value2, ... ), where keys and values are ASTLiteral or ASTIdentifier
* into * into
* <root_name> * <disk>
* <key1>value1</key1> * <key1>value1</key1>
* <key2>value2</key2> * <key2>value2</key2>
* ... * ...
* </root_name> * </disk>
* *
* Used in case disk configuration is passed via AST when creating * Used in case disk configuration is passed via AST when creating
* a disk object on-the-fly without any configuration file. * a disk object on-the-fly without any configuration file.
*/ */
DiskConfigurationPtr getDiskConfigurationFromAST(const std::string & root_name, const ASTs & disk_args, ContextPtr context); DiskConfigurationPtr getDiskConfigurationFromAST(const ASTs & disk_args, ContextPtr context);
/// The same as above function, but return XML::Document for easier modification of result configuration. /// The same as above function, but return XML::Document for easier modification of result configuration.
[[ maybe_unused ]] Poco::AutoPtr<Poco::XML::Document> getDiskConfigurationFromASTImpl(const std::string & root_name, const ASTs & disk_args, ContextPtr context); [[ maybe_unused ]] Poco::AutoPtr<Poco::XML::Document> getDiskConfigurationFromASTImpl(const ASTs & disk_args, ContextPtr context);
/* /*
* A reverse function. * A reverse function.

View File

@ -26,8 +26,16 @@ namespace
{ {
std::string getOrCreateDiskFromDiskAST(const ASTFunction & function, ContextPtr context) std::string getOrCreateDiskFromDiskAST(const ASTFunction & function, ContextPtr context)
{ {
const auto * function_args_expr = assert_cast<const ASTExpressionList *>(function.arguments.get());
const auto & function_args = function_args_expr->children;
auto config = getDiskConfigurationFromAST(function_args, context);
std::string disk_name; std::string disk_name;
if (function.name == "disk") if (config->has("name"))
{
disk_name = config->getString("name");
}
else
{ {
/// We need a unique name for a created custom disk, but it needs to be the same /// We need a unique name for a created custom disk, but it needs to be the same
/// after table is reattached or server is restarted, so take a hash of the disk /// after table is reattached or server is restarted, so take a hash of the disk
@ -36,21 +44,9 @@ namespace
disk_name = DiskSelector::TMP_INTERNAL_DISK_PREFIX disk_name = DiskSelector::TMP_INTERNAL_DISK_PREFIX
+ toString(sipHash128(disk_setting_string.data(), disk_setting_string.size())); + toString(sipHash128(disk_setting_string.data(), disk_setting_string.size()));
} }
else
{
static constexpr std::string_view custom_disk_prefix = "disk_";
if (function.name.size() <= custom_disk_prefix.size() || !function.name.starts_with(custom_disk_prefix))
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Invalid disk name: {}", function.name);
disk_name = function.name.substr(custom_disk_prefix.size());
}
auto result_disk = context->getOrCreateDisk(disk_name, [&](const DisksMap & disks_map) -> DiskPtr { auto result_disk = context->getOrCreateDisk(disk_name, [&](const DisksMap & disks_map) -> DiskPtr {
const auto * function_args_expr = assert_cast<const ASTExpressionList *>(function.arguments.get()); auto disk = DiskFactory::instance().create(disk_name, *config, "", context, disks_map);
const auto & function_args = function_args_expr->children;
auto config = getDiskConfigurationFromAST(disk_name, function_args, context);
auto disk = DiskFactory::instance().create(disk_name, *config, disk_name, context, disks_map);
/// Mark that disk can be used without storage policy. /// Mark that disk can be used without storage policy.
disk->markDiskAsCustom(); disk->markDiskAsCustom();
return disk; return disk;

View File

@ -783,7 +783,7 @@ namespace
if (!outcome.IsSuccess()) if (!outcome.IsSuccess())
{ {
abortMultipartUpload(); abortMultipartUpload();
throw Exception::createDeprecated(outcome.GetError().GetMessage(), ErrorCodes::S3_ERROR); throw S3Exception(outcome.GetError().GetMessage(), outcome.GetError().GetErrorType());
} }
return outcome.GetResult().GetCopyPartResult().GetETag(); return outcome.GetResult().GetCopyPartResult().GetETag();

View File

@ -85,7 +85,7 @@ ObjectInfo getObjectInfo(
} }
else if (throw_on_error) else if (throw_on_error)
{ {
throw DB::Exception(ErrorCodes::S3_ERROR, throw S3Exception(error.GetErrorType(),
"Failed to get object info: {}. HTTP response code: {}", "Failed to get object info: {}. HTTP response code: {}",
error.GetMessage(), static_cast<size_t>(error.GetResponseCode())); error.GetMessage(), static_cast<size_t>(error.GetResponseCode()));
} }

View File

@ -764,7 +764,7 @@ InterpreterCreateQuery::TableProperties InterpreterCreateQuery::getTableProperti
/// Table function without columns list. /// Table function without columns list.
auto table_function_ast = create.as_table_function->ptr(); auto table_function_ast = create.as_table_function->ptr();
auto table_function = TableFunctionFactory::instance().get(table_function_ast, getContext()); auto table_function = TableFunctionFactory::instance().get(table_function_ast, getContext());
properties.columns = table_function->getActualTableStructure(getContext()); properties.columns = table_function->getActualTableStructure(getContext(), /*is_insert_query*/ true);
} }
else if (create.is_dictionary) else if (create.is_dictionary)
{ {

View File

@ -96,7 +96,7 @@ BlockIO InterpreterDescribeQuery::execute()
else if (table_expression.table_function) else if (table_expression.table_function)
{ {
TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_expression.table_function, getContext()); TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_expression.table_function, getContext());
auto table_function_column_descriptions = table_function_ptr->getActualTableStructure(getContext()); auto table_function_column_descriptions = table_function_ptr->getActualTableStructure(getContext(), /*is_insert_query*/ true);
for (const auto & table_function_column_description : table_function_column_descriptions) for (const auto & table_function_column_description : table_function_column_descriptions)
columns.emplace_back(table_function_column_description); columns.emplace_back(table_function_column_description);
} }

View File

@ -215,7 +215,7 @@ bool ParserSetQuery::parseNameValuePair(SettingChange & change, IParser::Pos & p
else if (ParserKeyword("FALSE").ignore(pos, expected)) else if (ParserKeyword("FALSE").ignore(pos, expected))
value = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(0))); value = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(0)));
/// for SETTINGS disk=disk(type='s3', path='', ...) /// for SETTINGS disk=disk(type='s3', path='', ...)
else if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name.starts_with("disk")) else if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name == "disk")
{ {
tryGetIdentifierNameInto(name, change.name); tryGetIdentifierNameInto(name, change.name);
change.value = createFieldFromAST(function_ast); change.value = createFieldFromAST(function_ast);
@ -280,7 +280,7 @@ bool ParserSetQuery::parseNameValuePairWithParameterOrDefault(
node = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(1))); node = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(1)));
else if (ParserKeyword("FALSE").ignore(pos, expected)) else if (ParserKeyword("FALSE").ignore(pos, expected))
node = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(0))); node = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(0)));
else if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name.starts_with("disk")) else if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name == "disk")
{ {
change.name = name; change.name = name;
change.value = createFieldFromAST(function_ast); change.value = createFieldFromAST(function_ast);

View File

@ -57,8 +57,8 @@ std::vector<String> S3DataLakeMetadataReadHelper::listFiles(
{ {
outcome = client->ListObjectsV2(request); outcome = client->ListObjectsV2(request);
if (!outcome.IsSuccess()) if (!outcome.IsSuccess())
throw Exception( throw S3Exception(
ErrorCodes::S3_ERROR, outcome.GetError().GetErrorType(),
"Could not list objects in bucket {} with key {}, S3 exception: {}, message: {}", "Could not list objects in bucket {} with key {}, S3 exception: {}, message: {}",
quoteString(bucket), quoteString(bucket),
quoteString(base_configuration.url.key), quoteString(base_configuration.url.key),

View File

@ -86,7 +86,7 @@ const std::unordered_set<std::string_view> optional_configuration_keys = {
bool isConnectionString(const std::string & candidate) bool isConnectionString(const std::string & candidate)
{ {
return candidate.starts_with("DefaultEndpointsProtocol"); return !candidate.starts_with("http");
} }
} }
@ -257,7 +257,7 @@ void registerStorageAzureBlob(StorageFactory & factory)
throw Exception(ErrorCodes::BAD_ARGUMENTS, "External data source must have arguments"); throw Exception(ErrorCodes::BAD_ARGUMENTS, "External data source must have arguments");
auto configuration = StorageAzureBlob::getConfiguration(engine_args, args.getLocalContext()); auto configuration = StorageAzureBlob::getConfiguration(engine_args, args.getLocalContext());
auto client = StorageAzureBlob::createClient(configuration); auto client = StorageAzureBlob::createClient(configuration, /* is_read_only */ false);
// Use format settings from global server context + settings from // Use format settings from global server context + settings from
// the SETTINGS clause of the create query. Settings from current // the SETTINGS clause of the create query. Settings from current
// session and user are ignored. // session and user are ignored.
@ -309,58 +309,113 @@ void registerStorageAzureBlob(StorageFactory & factory)
}); });
} }
AzureClientPtr StorageAzureBlob::createClient(StorageAzureBlob::Configuration configuration) static bool containerExists(std::unique_ptr<BlobServiceClient> &blob_service_client, std::string container_name)
{
Azure::Storage::Blobs::ListBlobContainersOptions options;
options.Prefix = container_name;
options.PageSizeHint = 1;
auto containers_list_response = blob_service_client->ListBlobContainers(options);
auto containers_list = containers_list_response.BlobContainers;
for (const auto & container : containers_list)
{
if (container_name == container.Name)
return true;
}
return false;
}
AzureClientPtr StorageAzureBlob::createClient(StorageAzureBlob::Configuration configuration, bool is_read_only)
{ {
AzureClientPtr result; AzureClientPtr result;
if (configuration.is_connection_string) if (configuration.is_connection_string)
{ {
std::unique_ptr<BlobServiceClient> blob_service_client = std::make_unique<BlobServiceClient>(BlobServiceClient::CreateFromConnectionString(configuration.connection_url));
result = std::make_unique<BlobContainerClient>(BlobContainerClient::CreateFromConnectionString(configuration.connection_url, configuration.container)); result = std::make_unique<BlobContainerClient>(BlobContainerClient::CreateFromConnectionString(configuration.connection_url, configuration.container));
result->CreateIfNotExists(); bool container_exists = containerExists(blob_service_client,configuration.container);
}
else if (!container_exists)
{
if (configuration.account_name.has_value() && configuration.account_key.has_value())
{ {
auto storage_shared_key_credential = std::make_shared<Azure::Storage::StorageSharedKeyCredential>(*configuration.account_name, *configuration.account_key); if (is_read_only)
auto blob_service_client = std::make_unique<BlobServiceClient>(configuration.connection_url, storage_shared_key_credential); throw Exception(
ErrorCodes::DATABASE_ACCESS_DENIED,
"AzureBlobStorage container does not exist '{}'",
configuration.container);
try try
{ {
result = std::make_unique<BlobContainerClient>(blob_service_client->CreateBlobContainer(configuration.container).Value); result->CreateIfNotExists();
} } catch (const Azure::Storage::StorageException & e)
catch (const Azure::Storage::StorageException & e)
{ {
if (e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict) if (!(e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict
{ && e.ReasonPhrase == "The specified container already exists."))
auto final_url = configuration.connection_url
+ (configuration.connection_url.back() == '/' ? "" : "/")
+ configuration.container;
result = std::make_unique<BlobContainerClient>(final_url, storage_shared_key_credential);
}
else
{ {
throw; throw;
} }
} }
} }
}
else
{
std::shared_ptr<Azure::Storage::StorageSharedKeyCredential> storage_shared_key_credential;
if (configuration.account_name.has_value() && configuration.account_key.has_value())
{
storage_shared_key_credential
= std::make_shared<Azure::Storage::StorageSharedKeyCredential>(*configuration.account_name, *configuration.account_key);
}
std::unique_ptr<BlobServiceClient> blob_service_client;
if (storage_shared_key_credential)
{
blob_service_client = std::make_unique<BlobServiceClient>(configuration.connection_url, storage_shared_key_credential);
}
else else
{ {
auto managed_identity_credential = std::make_shared<Azure::Identity::ManagedIdentityCredential>(); blob_service_client = std::make_unique<BlobServiceClient>(configuration.connection_url);
auto blob_service_client = std::make_unique<BlobServiceClient>(configuration.connection_url, managed_identity_credential); }
bool container_exists = containerExists(blob_service_client,configuration.container);
std::string final_url;
size_t pos = configuration.connection_url.find('?');
if (pos != std::string::npos)
{
auto url_without_sas = configuration.connection_url.substr(0, pos);
final_url = url_without_sas + (url_without_sas.back() == '/' ? "" : "/") + configuration.container
+ configuration.connection_url.substr(pos);
}
else
final_url
= configuration.connection_url + (configuration.connection_url.back() == '/' ? "" : "/") + configuration.container;
if (container_exists)
{
if (storage_shared_key_credential)
result = std::make_unique<BlobContainerClient>(final_url, storage_shared_key_credential);
else
result = std::make_unique<BlobContainerClient>(final_url);
}
else
{
if (is_read_only)
throw Exception(
ErrorCodes::DATABASE_ACCESS_DENIED,
"AzureBlobStorage container does not exist '{}'",
configuration.container);
try try
{ {
result = std::make_unique<BlobContainerClient>(blob_service_client->CreateBlobContainer(configuration.container).Value); result = std::make_unique<BlobContainerClient>(blob_service_client->CreateBlobContainer(configuration.container).Value);
} } catch (const Azure::Storage::StorageException & e)
catch (const Azure::Storage::StorageException & e)
{ {
if (e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict) if (e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict
&& e.ReasonPhrase == "The specified container already exists.")
{ {
auto final_url = configuration.connection_url if (storage_shared_key_credential)
+ (configuration.connection_url.back() == '/' ? "" : "/") result = std::make_unique<BlobContainerClient>(final_url, storage_shared_key_credential);
+ configuration.container; else
result = std::make_unique<BlobContainerClient>(final_url);
result = std::make_unique<BlobContainerClient>(final_url, managed_identity_credential);
} }
else else
{ {
@ -438,7 +493,7 @@ void StorageAzureBlob::truncate(const ASTPtr &, const StorageMetadataPtr &, Cont
{ {
throw Exception( throw Exception(
ErrorCodes::DATABASE_ACCESS_DENIED, ErrorCodes::DATABASE_ACCESS_DENIED,
"S3 key '{}' contains globs, so the table is in readonly mode", "AzureBlobStorage key '{}' contains globs, so the table is in readonly mode",
configuration.blob_path); configuration.blob_path);
} }
@ -1203,7 +1258,7 @@ ColumnsDescription StorageAzureBlob::getTableStructureFromData(
return nullptr; return nullptr;
} }
/// S3 file iterator could get new keys after new iteration, check them in schema cache. ///AzureBlobStorage file iterator could get new keys after new iteration, check them in schema cache.
if (ctx->getSettingsRef().schema_inference_use_cache_for_azure && read_keys.size() > prev_read_keys_size) if (ctx->getSettingsRef().schema_inference_use_cache_for_azure && read_keys.size() > prev_read_keys_size)
{ {
columns_from_cache = tryGetColumnsFromCache(read_keys.begin() + prev_read_keys_size, read_keys.end(), configuration, format_settings, ctx); columns_from_cache = tryGetColumnsFromCache(read_keys.begin() + prev_read_keys_size, read_keys.end(), configuration, format_settings, ctx);

View File

@ -65,7 +65,7 @@ public:
ASTPtr partition_by_); ASTPtr partition_by_);
static StorageAzureBlob::Configuration getConfiguration(ASTs & engine_args, ContextPtr local_context); static StorageAzureBlob::Configuration getConfiguration(ASTs & engine_args, ContextPtr local_context);
static AzureClientPtr createClient(StorageAzureBlob::Configuration configuration); static AzureClientPtr createClient(StorageAzureBlob::Configuration configuration, bool is_read_only);
static AzureObjectStorage::SettingsPtr createSettings(ContextPtr local_context); static AzureObjectStorage::SettingsPtr createSettings(ContextPtr local_context);

View File

@ -245,7 +245,7 @@ private:
if (!outcome.IsSuccess()) if (!outcome.IsSuccess())
{ {
throw Exception(ErrorCodes::S3_ERROR, "Could not list objects in bucket {} with prefix {}, S3 exception: {}, message: {}", throw S3Exception(outcome.GetError().GetErrorType(), "Could not list objects in bucket {} with prefix {}, S3 exception: {}, message: {}",
quoteString(request.GetBucket()), quoteString(request.GetPrefix()), quoteString(request.GetBucket()), quoteString(request.GetPrefix()),
backQuote(outcome.GetError().GetExceptionName()), quoteString(outcome.GetError().GetMessage())); backQuote(outcome.GetError().GetExceptionName()), quoteString(outcome.GetError().GetMessage()));
} }
@ -1195,7 +1195,7 @@ void StorageS3::truncate(const ASTPtr & /* query */, const StorageMetadataPtr &,
if (!response.IsSuccess()) if (!response.IsSuccess())
{ {
const auto & err = response.GetError(); const auto & err = response.GetError();
throw Exception(ErrorCodes::S3_ERROR, "{}: {}", std::to_string(static_cast<int>(err.GetErrorType())), err.GetMessage()); throw S3Exception(err.GetMessage(), err.GetErrorType());
} }
for (const auto & error : response.GetResult().GetErrors()) for (const auto & error : response.GetResult().GetErrors())

View File

@ -77,6 +77,8 @@ struct S3Settings
const PartUploadSettings & getUploadSettings() const { return upload_settings; } const PartUploadSettings & getUploadSettings() const { return upload_settings; }
void setStorageClassName(const String & storage_class_name) { upload_settings.storage_class_name = storage_class_name; }
RequestSettings() = default; RequestSettings() = default;
explicit RequestSettings(const Settings & settings); explicit RequestSettings(const Settings & settings);
explicit RequestSettings(const NamedCollection & collection); explicit RequestSettings(const NamedCollection & collection);

View File

@ -38,7 +38,7 @@ ColumnsDescription getStructureOfRemoteTableInShard(
if (shard_info.isLocal()) if (shard_info.isLocal())
{ {
TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_func_ptr, context); TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_func_ptr, context);
return table_function_ptr->getActualTableStructure(context); return table_function_ptr->getActualTableStructure(context, /*is_insert_query*/ true);
} }
auto table_func_name = queryToString(table_func_ptr); auto table_func_name = queryToString(table_func_ptr);

View File

@ -49,13 +49,14 @@ namespace DB
actual_columns = parseColumnsListFromString(table_structure, context_); actual_columns = parseColumnsListFromString(table_structure, context_);
} }
ColumnsDescription TableFunctionHive::getActualTableStructure(ContextPtr /*context_*/) const { return actual_columns; } ColumnsDescription TableFunctionHive::getActualTableStructure(ContextPtr /*context_*/, bool /*is_insert_query*/) const { return actual_columns; }
StoragePtr TableFunctionHive::executeImpl( StoragePtr TableFunctionHive::executeImpl(
const ASTPtr & /*ast_function_*/, const ASTPtr & /*ast_function_*/,
ContextPtr context_, ContextPtr context_,
const std::string & table_name_, const std::string & table_name_,
ColumnsDescription /*cached_columns_*/) const ColumnsDescription /*cached_columns_*/,
bool /*is_insert_query*/) const
{ {
const Settings & settings = context_->getSettings(); const Settings & settings = context_->getSettings();
ParserExpression partition_by_parser; ParserExpression partition_by_parser;

View File

@ -17,10 +17,10 @@ public:
bool hasStaticStructure() const override { return true; } bool hasStaticStructure() const override { return true; }
StoragePtr executeImpl( StoragePtr executeImpl(
const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return storage_type_name; } const char * getStorageTypeName() const override { return storage_type_name; }
ColumnsDescription getActualTableStructure(ContextPtr) const override; ColumnsDescription getActualTableStructure(ContextPtr, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function_, ContextPtr context_) override; void parseArguments(const ASTPtr & ast_function_, ContextPtr context_) override;
private: private:

View File

@ -34,15 +34,15 @@ StoragePtr ITableFunction::execute(const ASTPtr & ast_function, ContextPtr conte
auto context_to_use = use_global_context ? context->getGlobalContext() : context; auto context_to_use = use_global_context ? context->getGlobalContext() : context;
if (cached_columns.empty()) if (cached_columns.empty())
return executeImpl(ast_function, context, table_name, std::move(cached_columns)); return executeImpl(ast_function, context, table_name, std::move(cached_columns), is_insert_query);
if (hasStaticStructure() && cached_columns == getActualTableStructure(context)) if (hasStaticStructure() && cached_columns == getActualTableStructure(context,is_insert_query))
return executeImpl(ast_function, context_to_use, table_name, std::move(cached_columns)); return executeImpl(ast_function, context_to_use, table_name, std::move(cached_columns), is_insert_query);
auto this_table_function = shared_from_this(); auto this_table_function = shared_from_this();
auto get_storage = [=]() -> StoragePtr auto get_storage = [=]() -> StoragePtr
{ {
return this_table_function->executeImpl(ast_function, context_to_use, table_name, cached_columns); return this_table_function->executeImpl(ast_function, context_to_use, table_name, cached_columns, is_insert_query);
}; };
/// It will request actual table structure and create underlying storage lazily /// It will request actual table structure and create underlying storage lazily

View File

@ -58,7 +58,7 @@ public:
virtual void parseArguments(const ASTPtr & /*ast_function*/, ContextPtr /*context*/) {} virtual void parseArguments(const ASTPtr & /*ast_function*/, ContextPtr /*context*/) {}
/// Returns actual table structure probably requested from remote server, may fail /// Returns actual table structure probably requested from remote server, may fail
virtual ColumnsDescription getActualTableStructure(ContextPtr /*context*/) const = 0; virtual ColumnsDescription getActualTableStructure(ContextPtr /*context*/, bool is_insert_query) const = 0;
/// Check if table function needs a structure hint from SELECT query in case of /// Check if table function needs a structure hint from SELECT query in case of
/// INSERT INTO FUNCTION ... SELECT ... and INSERT INTO ... SELECT ... FROM table_function(...) /// INSERT INTO FUNCTION ... SELECT ... and INSERT INTO ... SELECT ... FROM table_function(...)
@ -89,7 +89,7 @@ protected:
private: private:
virtual StoragePtr executeImpl( virtual StoragePtr executeImpl(
const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const = 0; const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const = 0;
virtual const char * getStorageTypeName() const = 0; virtual const char * getStorageTypeName() const = 0;
}; };

View File

@ -26,7 +26,8 @@ protected:
const ASTPtr & /*ast_function*/, const ASTPtr & /*ast_function*/,
ContextPtr context, ContextPtr context,
const std::string & table_name, const std::string & table_name,
ColumnsDescription /*cached_columns*/) const override ColumnsDescription /*cached_columns*/,
bool /*is_insert_query*/) const override
{ {
ColumnsDescription columns; ColumnsDescription columns;
if (TableFunction::configuration.structure != "auto") if (TableFunction::configuration.structure != "auto")
@ -42,7 +43,7 @@ protected:
const char * getStorageTypeName() const override { return Storage::name; } const char * getStorageTypeName() const override { return Storage::name; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override ColumnsDescription getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const override
{ {
if (TableFunction::configuration.structure == "auto") if (TableFunction::configuration.structure == "auto")
{ {

View File

@ -110,7 +110,7 @@ void ITableFunctionFileLike::addColumnsStructureToArguments(ASTs & args, const S
} }
} }
StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
ColumnsDescription columns; ColumnsDescription columns;
if (structure != "auto") if (structure != "auto")

View File

@ -48,7 +48,7 @@ protected:
ColumnsDescription structure_hint; ColumnsDescription structure_hint;
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
virtual StoragePtr getStorage( virtual StoragePtr getStorage(
const String & source, const String & format, const ColumnsDescription & columns, ContextPtr global_context, const String & source, const String & format, const ColumnsDescription & columns, ContextPtr global_context,

View File

@ -61,7 +61,7 @@ void ITableFunctionXDBC::startBridgeIfNot(ContextPtr context) const
} }
} }
ColumnsDescription ITableFunctionXDBC::getActualTableStructure(ContextPtr context) const ColumnsDescription ITableFunctionXDBC::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
startBridgeIfNot(context); startBridgeIfNot(context);
@ -92,10 +92,10 @@ ColumnsDescription ITableFunctionXDBC::getActualTableStructure(ContextPtr contex
return ColumnsDescription{columns}; return ColumnsDescription{columns};
} }
StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
startBridgeIfNot(context); startBridgeIfNot(context);
auto columns = getActualTableStructure(context); auto columns = getActualTableStructure(context, is_insert_query);
auto result = std::make_shared<StorageXDBC>( auto result = std::make_shared<StorageXDBC>(
StorageID(getDatabaseName(), table_name), schema_name, remote_table_name, columns, ConstraintsDescription{}, String{}, context, helper); StorageID(getDatabaseName(), table_name), schema_name, remote_table_name, columns, ConstraintsDescription{}, String{}, context, helper);
result->startup(); result->startup();

View File

@ -16,7 +16,7 @@ namespace DB
class ITableFunctionXDBC : public ITableFunction class ITableFunctionXDBC : public ITableFunction
{ {
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
/* A factory method to create bridge helper, that will assist in remote interaction */ /* A factory method to create bridge helper, that will assist in remote interaction */
virtual BridgeHelperPtr createBridgeHelper(ContextPtr context, virtual BridgeHelperPtr createBridgeHelper(ContextPtr context,
@ -24,7 +24,7 @@ private:
const std::string & connection_string_, const std::string & connection_string_,
bool use_connection_pooling_) const = 0; bool use_connection_pooling_) const = 0;
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;

View File

@ -39,7 +39,7 @@ namespace
bool isConnectionString(const std::string & candidate) bool isConnectionString(const std::string & candidate)
{ {
return candidate.starts_with("DefaultEndpointsProtocol"); return !candidate.starts_with("http");
} }
} }
@ -193,12 +193,12 @@ void TableFunctionAzureBlobStorage::parseArguments(const ASTPtr & ast_function,
configuration = parseArgumentsImpl(args, context); configuration = parseArgumentsImpl(args, context);
} }
ColumnsDescription TableFunctionAzureBlobStorage::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionAzureBlobStorage::getActualTableStructure(ContextPtr context, bool is_insert_query) const
{ {
if (configuration.structure == "auto") if (configuration.structure == "auto")
{ {
context->checkAccess(getSourceAccessType()); context->checkAccess(getSourceAccessType());
auto client = StorageAzureBlob::createClient(configuration); auto client = StorageAzureBlob::createClient(configuration, !is_insert_query);
auto settings = StorageAzureBlob::createSettings(context); auto settings = StorageAzureBlob::createSettings(context);
auto object_storage = std::make_unique<AzureObjectStorage>("AzureBlobStorageTableFunction", std::move(client), std::move(settings)); auto object_storage = std::make_unique<AzureObjectStorage>("AzureBlobStorageTableFunction", std::move(client), std::move(settings));
@ -213,9 +213,9 @@ bool TableFunctionAzureBlobStorage::supportsReadingSubsetOfColumns()
return FormatFactory::instance().checkIfFormatSupportsSubsetOfColumns(configuration.format); return FormatFactory::instance().checkIfFormatSupportsSubsetOfColumns(configuration.format);
} }
StoragePtr TableFunctionAzureBlobStorage::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionAzureBlobStorage::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
auto client = StorageAzureBlob::createClient(configuration); auto client = StorageAzureBlob::createClient(configuration, !is_insert_query);
auto settings = StorageAzureBlob::createSettings(context); auto settings = StorageAzureBlob::createSettings(context);
ColumnsDescription columns; ColumnsDescription columns;

View File

@ -54,11 +54,12 @@ protected:
const ASTPtr & ast_function, const ASTPtr & ast_function,
ContextPtr context, ContextPtr context,
const std::string & table_name, const std::string & table_name,
ColumnsDescription cached_columns) const override; ColumnsDescription cached_columns,
bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Azure"; } const char * getStorageTypeName() const override { return "Azure"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
mutable StorageAzureBlob::Configuration configuration; mutable StorageAzureBlob::Configuration configuration;

View File

@ -43,7 +43,7 @@ void TableFunctionDictionary::parseArguments(const ASTPtr & ast_function, Contex
dictionary_name = checkAndGetLiteralArgument<String>(args[0], "dictionary_name"); dictionary_name = checkAndGetLiteralArgument<String>(args[0], "dictionary_name");
} }
ColumnsDescription TableFunctionDictionary::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionDictionary::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
const ExternalDictionariesLoader & external_loader = context->getExternalDictionariesLoader(); const ExternalDictionariesLoader & external_loader = context->getExternalDictionariesLoader();
std::string resolved_name = external_loader.resolveDictionaryName(dictionary_name, context->getCurrentDatabase()); std::string resolved_name = external_loader.resolveDictionaryName(dictionary_name, context->getCurrentDatabase());
@ -76,10 +76,10 @@ ColumnsDescription TableFunctionDictionary::getActualTableStructure(ContextPtr c
} }
StoragePtr TableFunctionDictionary::executeImpl( StoragePtr TableFunctionDictionary::executeImpl(
const ASTPtr &, ContextPtr context, const std::string & table_name, ColumnsDescription) const const ASTPtr &, ContextPtr context, const std::string & table_name, ColumnsDescription, bool is_insert_query) const
{ {
StorageID dict_id(getDatabaseName(), table_name); StorageID dict_id(getDatabaseName(), table_name);
auto dictionary_table_structure = getActualTableStructure(context); auto dictionary_table_structure = getActualTableStructure(context, is_insert_query);
auto result = std::make_shared<StorageDictionary>( auto result = std::make_shared<StorageDictionary>(
dict_id, dictionary_name, std::move(dictionary_table_structure), String{}, StorageDictionary::Location::Custom, context); dict_id, dictionary_name, std::move(dictionary_table_structure), String{}, StorageDictionary::Location::Custom, context);

View File

@ -18,9 +18,9 @@ public:
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Dictionary"; } const char * getStorageTypeName() const override { return "Dictionary"; }

View File

@ -120,12 +120,12 @@ void TableFunctionExecutable::parseArguments(const ASTPtr & ast_function, Contex
} }
} }
ColumnsDescription TableFunctionExecutable::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionExecutable::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
return parseColumnsListFromString(structure, context); return parseColumnsListFromString(structure, context);
} }
StoragePtr TableFunctionExecutable::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionExecutable::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
auto storage_id = StorageID(getDatabaseName(), table_name); auto storage_id = StorageID(getDatabaseName(), table_name);
auto global_context = context->getGlobalContext(); auto global_context = context->getGlobalContext();
@ -135,7 +135,7 @@ StoragePtr TableFunctionExecutable::executeImpl(const ASTPtr & /*ast_function*/,
if (settings_query != nullptr) if (settings_query != nullptr)
settings.applyChanges(settings_query->as<ASTSetQuery>()->changes); settings.applyChanges(settings_query->as<ASTSetQuery>()->changes);
auto storage = std::make_shared<StorageExecutable>(storage_id, format, settings, input_queries, getActualTableStructure(context), ConstraintsDescription{}); auto storage = std::make_shared<StorageExecutable>(storage_id, format, settings, input_queries, getActualTableStructure(context, is_insert_query), ConstraintsDescription{});
storage->startup(); storage->startup();
return storage; return storage;
} }

View File

@ -24,11 +24,11 @@ public:
bool hasStaticStructure() const override { return true; } bool hasStaticStructure() const override { return true; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Executable"; } const char * getStorageTypeName() const override { return "Executable"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
std::vector<size_t> skipAnalysisForArguments(const QueryTreeNodePtr & query_node_table_function, ContextPtr context) const override; std::vector<size_t> skipAnalysisForArguments(const QueryTreeNodePtr & query_node_table_function, ContextPtr context) const override;

View File

@ -91,7 +91,7 @@ void TableFunctionExplain::parseArguments(const ASTPtr & ast_function, ContextPt
query = std::move(explain_query); query = std::move(explain_query);
} }
ColumnsDescription TableFunctionExplain::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionExplain::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
Block sample_block = getInterpreter(context).getSampleBlock(query->as<ASTExplainQuery>()->getKind()); Block sample_block = getInterpreter(context).getSampleBlock(query->as<ASTExplainQuery>()->getKind());
ColumnsDescription columns_description; ColumnsDescription columns_description;
@ -123,7 +123,7 @@ static Block executeMonoBlock(QueryPipeline & pipeline)
} }
StoragePtr TableFunctionExplain::executeImpl( StoragePtr TableFunctionExplain::executeImpl(
const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
/// To support settings inside explain subquery. /// To support settings inside explain subquery.
auto mutable_context = Context::createCopy(context); auto mutable_context = Context::createCopy(context);
@ -132,7 +132,7 @@ StoragePtr TableFunctionExplain::executeImpl(
Block block = executeMonoBlock(blockio.pipeline); Block block = executeMonoBlock(blockio.pipeline);
StorageID storage_id(getDatabaseName(), table_name); StorageID storage_id(getDatabaseName(), table_name);
auto storage = std::make_shared<StorageValues>(storage_id, getActualTableStructure(context), std::move(block)); auto storage = std::make_shared<StorageValues>(storage_id, getActualTableStructure(context, is_insert_query), std::move(block));
storage->startup(); storage->startup();
return storage; return storage;
} }

View File

@ -17,7 +17,7 @@ public:
std::string getName() const override { return name; } std::string getName() const override { return name; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const String & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const String & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Explain"; } const char * getStorageTypeName() const override { return "Explain"; }
@ -25,7 +25,7 @@ private:
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
InterpreterExplainQuery getInterpreter(ContextPtr context) const; InterpreterExplainQuery getInterpreter(ContextPtr context) const;

View File

@ -83,7 +83,7 @@ StoragePtr TableFunctionFile::getStorage(const String & source,
return std::make_shared<StorageFile>(source, global_context->getUserFilesPath(), args); return std::make_shared<StorageFile>(source, global_context->getUserFilesPath(), args);
} }
ColumnsDescription TableFunctionFile::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionFile::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
if (structure == "auto") if (structure == "auto")
{ {

View File

@ -20,7 +20,7 @@ public:
return name; return name;
} }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
std::unordered_set<String> getVirtualsToCheckBeforeUsingStructureHint() const override std::unordered_set<String> getVirtualsToCheckBeforeUsingStructureHint() const override
{ {

View File

@ -52,7 +52,7 @@ void TableFunctionFormat::parseArguments(const ASTPtr & ast_function, ContextPtr
structure = checkAndGetLiteralArgument<String>(args[1], "structure"); structure = checkAndGetLiteralArgument<String>(args[1], "structure");
} }
ColumnsDescription TableFunctionFormat::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionFormat::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
if (structure == "auto") if (structure == "auto")
{ {
@ -98,9 +98,9 @@ Block TableFunctionFormat::parseData(ColumnsDescription columns, ContextPtr cont
return concatenateBlocks(blocks); return concatenateBlocks(blocks);
} }
StoragePtr TableFunctionFormat::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionFormat::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
auto columns = getActualTableStructure(context); auto columns = getActualTableStructure(context, is_insert_query);
Block res_block = parseData(columns, context); Block res_block = parseData(columns, context);
auto res = std::make_shared<StorageValues>(StorageID(getDatabaseName(), table_name), columns, res_block); auto res = std::make_shared<StorageValues>(StorageID(getDatabaseName(), table_name), columns, res_block);
res->startup(); res->startup();

View File

@ -18,10 +18,10 @@ public:
bool hasStaticStructure() const override { return false; } bool hasStaticStructure() const override { return false; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Values"; } const char * getStorageTypeName() const override { return "Values"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
Block parseData(ColumnsDescription columns, ContextPtr context) const; Block parseData(ColumnsDescription columns, ContextPtr context) const;

View File

@ -97,7 +97,7 @@ void TableFunctionGenerateRandom::parseArguments(const ASTPtr & ast_function, Co
} }
} }
ColumnsDescription TableFunctionGenerateRandom::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionGenerateRandom::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
if (structure == "auto") if (structure == "auto")
{ {
@ -113,9 +113,9 @@ ColumnsDescription TableFunctionGenerateRandom::getActualTableStructure(ContextP
return parseColumnsListFromString(structure, context); return parseColumnsListFromString(structure, context);
} }
StoragePtr TableFunctionGenerateRandom::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionGenerateRandom::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
ColumnsDescription columns = getActualTableStructure(context); ColumnsDescription columns = getActualTableStructure(context, is_insert_query);
auto res = std::make_shared<StorageGenerateRandom>( auto res = std::make_shared<StorageGenerateRandom>(
StorageID(getDatabaseName(), table_name), columns, String{}, max_array_length, max_string_length, random_seed); StorageID(getDatabaseName(), table_name), columns, String{}, max_array_length, max_string_length, random_seed);
res->startup(); res->startup();

View File

@ -19,10 +19,10 @@ public:
void setStructureHint(const ColumnsDescription & structure_hint_) override { structure_hint = structure_hint_; } void setStructureHint(const ColumnsDescription & structure_hint_) override { structure_hint = structure_hint_; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "GenerateRandom"; } const char * getStorageTypeName() const override { return "GenerateRandom"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
String structure = "auto"; String structure = "auto";

View File

@ -28,7 +28,7 @@ StoragePtr TableFunctionHDFS::getStorage(
compression_method_); compression_method_);
} }
ColumnsDescription TableFunctionHDFS::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionHDFS::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
if (structure == "auto") if (structure == "auto")
{ {

View File

@ -34,7 +34,7 @@ public:
return signature; return signature;
} }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
std::unordered_set<String> getVirtualsToCheckBeforeUsingStructureHint() const override std::unordered_set<String> getVirtualsToCheckBeforeUsingStructureHint() const override
{ {

View File

@ -43,7 +43,7 @@ void TableFunctionInput::parseArguments(const ASTPtr & ast_function, ContextPtr
structure = checkAndGetLiteralArgument<String>(evaluateConstantExpressionOrIdentifierAsLiteral(args[0], context), "structure"); structure = checkAndGetLiteralArgument<String>(evaluateConstantExpressionOrIdentifierAsLiteral(args[0], context), "structure");
} }
ColumnsDescription TableFunctionInput::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionInput::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
if (structure == "auto") if (structure == "auto")
{ {
@ -58,9 +58,9 @@ ColumnsDescription TableFunctionInput::getActualTableStructure(ContextPtr contex
return parseColumnsListFromString(structure, context); return parseColumnsListFromString(structure, context);
} }
StoragePtr TableFunctionInput::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionInput::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
auto storage = std::make_shared<StorageInput>(StorageID(getDatabaseName(), table_name), getActualTableStructure(context)); auto storage = std::make_shared<StorageInput>(StorageID(getDatabaseName(), table_name), getActualTableStructure(context, is_insert_query));
storage->startup(); storage->startup();
return storage; return storage;
} }

View File

@ -20,10 +20,10 @@ public:
void setStructureHint(const ColumnsDescription & structure_hint_) override { structure_hint = structure_hint_; } void setStructureHint(const ColumnsDescription & structure_hint_) override { structure_hint = structure_hint_; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Input"; } const char * getStorageTypeName() const override { return "Input"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
String structure; String structure;

View File

@ -8,13 +8,13 @@
namespace DB namespace DB
{ {
StoragePtr TableFunctionMeiliSearch::executeImpl( StoragePtr TableFunctionMeiliSearch::executeImpl(
const ASTPtr & /* ast_function */, ContextPtr /*context*/, const String & table_name, ColumnsDescription /*cached_columns*/) const const ASTPtr & /* ast_function */, ContextPtr /*context*/, const String & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
return std::make_shared<StorageMeiliSearch>( return std::make_shared<StorageMeiliSearch>(
StorageID(getDatabaseName(), table_name), configuration.value(), ColumnsDescription{}, ConstraintsDescription{}, String{}); StorageID(getDatabaseName(), table_name), configuration.value(), ColumnsDescription{}, ConstraintsDescription{}, String{});
} }
ColumnsDescription TableFunctionMeiliSearch::getActualTableStructure(ContextPtr /* context */) const ColumnsDescription TableFunctionMeiliSearch::getActualTableStructure(ContextPtr /* context */, bool /*is_insert_query*/) const
{ {
return StorageMeiliSearch::getTableStructureFromData(configuration.value()); return StorageMeiliSearch::getTableStructureFromData(configuration.value());
} }

View File

@ -13,11 +13,11 @@ public:
private: private:
StoragePtr executeImpl( StoragePtr executeImpl(
const ASTPtr & ast_function, ContextPtr context, const String & table_name, ColumnsDescription cached_columns) const override; const ASTPtr & ast_function, ContextPtr context, const String & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "meilisearch"; } const char * getStorageTypeName() const override { return "meilisearch"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
std::optional<MeiliSearchConfiguration> configuration; std::optional<MeiliSearchConfiguration> configuration;

View File

@ -118,7 +118,7 @@ const TableFunctionMerge::DBToTableSetMap & TableFunctionMerge::getSourceDatabas
return *source_databases_and_tables; return *source_databases_and_tables;
} }
ColumnsDescription TableFunctionMerge::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionMerge::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
for (const auto & db_with_tables : getSourceDatabasesAndTables(context)) for (const auto & db_with_tables : getSourceDatabasesAndTables(context))
{ {
@ -134,11 +134,11 @@ ColumnsDescription TableFunctionMerge::getActualTableStructure(ContextPtr contex
} }
StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
auto res = std::make_shared<StorageMerge>( auto res = std::make_shared<StorageMerge>(
StorageID(getDatabaseName(), table_name), StorageID(getDatabaseName(), table_name),
getActualTableStructure(context), getActualTableStructure(context, is_insert_query),
String{}, String{},
source_database_name_or_regexp, source_database_name_or_regexp,
database_is_regexp, database_is_regexp,

View File

@ -17,13 +17,13 @@ public:
std::string getName() const override { return name; } std::string getName() const override { return name; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Merge"; } const char * getStorageTypeName() const override { return "Merge"; }
using TableSet = std::set<String>; using TableSet = std::set<String>;
using DBToTableSetMap = std::map<String, TableSet>; using DBToTableSetMap = std::map<String, TableSet>;
const DBToTableSetMap & getSourceDatabasesAndTables(ContextPtr context) const; const DBToTableSetMap & getSourceDatabasesAndTables(ContextPtr context) const;
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
std::vector<size_t> skipAnalysisForArguments(const QueryTreeNodePtr & query_node_table_function, ContextPtr context) const override; std::vector<size_t> skipAnalysisForArguments(const QueryTreeNodePtr & query_node_table_function, ContextPtr context) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
static TableSet getMatchedTablesWithAccess(const String & database_name, const String & table_regexp, const ContextPtr & context); static TableSet getMatchedTablesWithAccess(const String & database_name, const String & table_regexp, const ContextPtr & context);

View File

@ -27,9 +27,9 @@ namespace ErrorCodes
StoragePtr TableFunctionMongoDB::executeImpl(const ASTPtr & /*ast_function*/, StoragePtr TableFunctionMongoDB::executeImpl(const ASTPtr & /*ast_function*/,
ContextPtr context, const String & table_name, ColumnsDescription /*cached_columns*/) const ContextPtr context, const String & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
auto columns = getActualTableStructure(context); auto columns = getActualTableStructure(context, is_insert_query);
auto storage = std::make_shared<StorageMongoDB>( auto storage = std::make_shared<StorageMongoDB>(
StorageID(configuration->database, table_name), StorageID(configuration->database, table_name),
configuration->host, configuration->host,
@ -46,7 +46,7 @@ StoragePtr TableFunctionMongoDB::executeImpl(const ASTPtr & /*ast_function*/,
return storage; return storage;
} }
ColumnsDescription TableFunctionMongoDB::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionMongoDB::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
return parseColumnsListFromString(structure, context); return parseColumnsListFromString(structure, context);
} }

View File

@ -17,11 +17,11 @@ public:
private: private:
StoragePtr executeImpl( StoragePtr executeImpl(
const ASTPtr & ast_function, ContextPtr context, const ASTPtr & ast_function, ContextPtr context,
const std::string & table_name, ColumnsDescription cached_columns) const override; const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "MongoDB"; } const char * getStorageTypeName() const override { return "MongoDB"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
std::optional<StorageMongoDB::Configuration> configuration; std::optional<StorageMongoDB::Configuration> configuration;

View File

@ -57,7 +57,7 @@ void TableFunctionMySQL::parseArguments(const ASTPtr & ast_function, ContextPtr
pool.emplace(createMySQLPoolWithFailover(*configuration, mysql_settings)); pool.emplace(createMySQLPoolWithFailover(*configuration, mysql_settings));
} }
ColumnsDescription TableFunctionMySQL::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionMySQL::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
return StorageMySQL::getTableStructureFromData(*pool, configuration->database, configuration->table, context); return StorageMySQL::getTableStructureFromData(*pool, configuration->database, configuration->table, context);
} }
@ -66,7 +66,8 @@ StoragePtr TableFunctionMySQL::executeImpl(
const ASTPtr & /*ast_function*/, const ASTPtr & /*ast_function*/,
ContextPtr context, ContextPtr context,
const std::string & table_name, const std::string & table_name,
ColumnsDescription /*cached_columns*/) const ColumnsDescription /*cached_columns*/,
bool /*is_insert_query*/) const
{ {
auto res = std::make_shared<StorageMySQL>( auto res = std::make_shared<StorageMySQL>(
StorageID(getDatabaseName(), table_name), StorageID(getDatabaseName(), table_name),

View File

@ -23,10 +23,10 @@ public:
return name; return name;
} }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "MySQL"; } const char * getStorageTypeName() const override { return "MySQL"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
mutable std::optional<mysqlxx::PoolWithFailover> pool; mutable std::optional<mysqlxx::PoolWithFailover> pool;

View File

@ -32,14 +32,14 @@ void TableFunctionNull::parseArguments(const ASTPtr & ast_function, ContextPtr c
structure = checkAndGetLiteralArgument<String>(evaluateConstantExpressionOrIdentifierAsLiteral(arguments[0], context), "structure"); structure = checkAndGetLiteralArgument<String>(evaluateConstantExpressionOrIdentifierAsLiteral(arguments[0], context), "structure");
} }
ColumnsDescription TableFunctionNull::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionNull::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
if (structure != "auto") if (structure != "auto")
return parseColumnsListFromString(structure, context); return parseColumnsListFromString(structure, context);
return default_structure; return default_structure;
} }
StoragePtr TableFunctionNull::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionNull::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
ColumnsDescription columns; ColumnsDescription columns;
if (structure != "auto") if (structure != "auto")

View File

@ -23,11 +23,11 @@ public:
void setStructureHint(const ColumnsDescription & structure_hint_) override { structure_hint = structure_hint_; } void setStructureHint(const ColumnsDescription & structure_hint_) override { structure_hint = structure_hint_; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const String & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const String & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Null"; } const char * getStorageTypeName() const override { return "Null"; }
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
String structure = "auto"; String structure = "auto";
ColumnsDescription structure_hint; ColumnsDescription structure_hint;

View File

@ -23,14 +23,14 @@ namespace ErrorCodes
template <bool multithreaded> template <bool multithreaded>
ColumnsDescription TableFunctionNumbers<multithreaded>::getActualTableStructure(ContextPtr /*context*/) const ColumnsDescription TableFunctionNumbers<multithreaded>::getActualTableStructure(ContextPtr /*context*/, bool /*is_insert_query*/) const
{ {
/// NOTE: https://bugs.llvm.org/show_bug.cgi?id=47418 /// NOTE: https://bugs.llvm.org/show_bug.cgi?id=47418
return ColumnsDescription{{{"number", std::make_shared<DataTypeUInt64>()}}}; return ColumnsDescription{{{"number", std::make_shared<DataTypeUInt64>()}}};
} }
template <bool multithreaded> template <bool multithreaded>
StoragePtr TableFunctionNumbers<multithreaded>::executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionNumbers<multithreaded>::executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
if (const auto * function = ast_function->as<ASTFunction>()) if (const auto * function = ast_function->as<ASTFunction>())
{ {

View File

@ -19,12 +19,12 @@ public:
std::string getName() const override { return name; } std::string getName() const override { return name; }
bool hasStaticStructure() const override { return true; } bool hasStaticStructure() const override { return true; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "SystemNumbers"; } const char * getStorageTypeName() const override { return "SystemNumbers"; }
UInt64 evaluateArgument(ContextPtr context, ASTPtr & argument) const; UInt64 evaluateArgument(ContextPtr context, ASTPtr & argument) const;
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
}; };

View File

@ -20,7 +20,7 @@ namespace ErrorCodes
StoragePtr TableFunctionPostgreSQL::executeImpl(const ASTPtr & /*ast_function*/, StoragePtr TableFunctionPostgreSQL::executeImpl(const ASTPtr & /*ast_function*/,
ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
auto result = std::make_shared<StoragePostgreSQL>( auto result = std::make_shared<StoragePostgreSQL>(
StorageID(getDatabaseName(), table_name), StorageID(getDatabaseName(), table_name),
@ -38,7 +38,7 @@ StoragePtr TableFunctionPostgreSQL::executeImpl(const ASTPtr & /*ast_function*/,
} }
ColumnsDescription TableFunctionPostgreSQL::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionPostgreSQL::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
return StoragePostgreSQL::getTableStructureFromData(connection_pool, configuration->table, configuration->schema, context); return StoragePostgreSQL::getTableStructureFromData(connection_pool, configuration->table, configuration->schema, context);
} }

View File

@ -20,11 +20,11 @@ public:
private: private:
StoragePtr executeImpl( StoragePtr executeImpl(
const ASTPtr & ast_function, ContextPtr context, const ASTPtr & ast_function, ContextPtr context,
const std::string & table_name, ColumnsDescription cached_columns) const override; const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "PostgreSQL"; } const char * getStorageTypeName() const override { return "PostgreSQL"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
postgres::PoolWithFailoverPtr connection_pool; postgres::PoolWithFailoverPtr connection_pool;

View File

@ -25,9 +25,9 @@ namespace ErrorCodes
} }
StoragePtr TableFunctionRedis::executeImpl( StoragePtr TableFunctionRedis::executeImpl(
const ASTPtr & /*ast_function*/, ContextPtr context, const String & table_name, ColumnsDescription /*cached_columns*/) const const ASTPtr & /*ast_function*/, ContextPtr context, const String & table_name, ColumnsDescription /*cached_columns*/, bool is_insert_query) const
{ {
auto columns = getActualTableStructure(context); auto columns = getActualTableStructure(context, is_insert_query);
StorageInMemoryMetadata metadata; StorageInMemoryMetadata metadata;
metadata.setColumns(columns); metadata.setColumns(columns);
@ -39,7 +39,7 @@ StoragePtr TableFunctionRedis::executeImpl(
return storage; return storage;
} }
ColumnsDescription TableFunctionRedis::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionRedis::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
return parseColumnsListFromString(structure, context); return parseColumnsListFromString(structure, context);
} }

View File

@ -19,11 +19,11 @@ public:
private: private:
StoragePtr executeImpl( StoragePtr executeImpl(
const ASTPtr & ast_function, ContextPtr context, const ASTPtr & ast_function, ContextPtr context,
const String & table_name, ColumnsDescription cached_columns) const override; const String & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Redis"; } const char * getStorageTypeName() const override { return "Redis"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
RedisConfiguration configuration; RedisConfiguration configuration;

View File

@ -276,12 +276,12 @@ void TableFunctionRemote::parseArguments(const ASTPtr & ast_function, ContextPtr
remote_table_id.table_name = table; remote_table_id.table_name = table;
} }
StoragePtr TableFunctionRemote::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const StoragePtr TableFunctionRemote::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const
{ {
/// StorageDistributed supports mismatching structure of remote table, so we can use outdated structure for CREATE ... AS remote(...) /// StorageDistributed supports mismatching structure of remote table, so we can use outdated structure for CREATE ... AS remote(...)
/// without additional conversion in StorageTableFunctionProxy /// without additional conversion in StorageTableFunctionProxy
if (cached_columns.empty()) if (cached_columns.empty())
cached_columns = getActualTableStructure(context); cached_columns = getActualTableStructure(context, is_insert_query);
assert(cluster); assert(cluster);
StoragePtr res = remote_table_function_ptr StoragePtr res = remote_table_function_ptr
@ -318,7 +318,7 @@ StoragePtr TableFunctionRemote::executeImpl(const ASTPtr & /*ast_function*/, Con
return res; return res;
} }
ColumnsDescription TableFunctionRemote::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionRemote::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
assert(cluster); assert(cluster);
return getStructureOfRemoteTable(*cluster, remote_table_id, context, remote_table_function_ptr); return getStructureOfRemoteTable(*cluster, remote_table_id, context, remote_table_function_ptr);

View File

@ -22,13 +22,13 @@ public:
std::string getName() const override { return name; } std::string getName() const override { return name; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
bool needStructureConversion() const override { return false; } bool needStructureConversion() const override { return false; }
private: private:
StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns) const override; StoragePtr executeImpl(const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "Distributed"; } const char * getStorageTypeName() const override { return "Distributed"; }
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;

View File

@ -313,7 +313,7 @@ void TableFunctionS3::addColumnsStructureToArguments(ASTs & args, const String &
} }
} }
ColumnsDescription TableFunctionS3::getActualTableStructure(ContextPtr context) const ColumnsDescription TableFunctionS3::getActualTableStructure(ContextPtr context, bool /*is_insert_query*/) const
{ {
if (configuration.structure == "auto") if (configuration.structure == "auto")
{ {
@ -330,7 +330,7 @@ bool TableFunctionS3::supportsReadingSubsetOfColumns()
return FormatFactory::instance().checkIfFormatSupportsSubsetOfColumns(configuration.format); return FormatFactory::instance().checkIfFormatSupportsSubsetOfColumns(configuration.format);
} }
StoragePtr TableFunctionS3::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const StoragePtr TableFunctionS3::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
S3::URI s3_uri (configuration.url); S3::URI s3_uri (configuration.url);

View File

@ -64,11 +64,12 @@ protected:
const ASTPtr & ast_function, const ASTPtr & ast_function,
ContextPtr context, ContextPtr context,
const std::string & table_name, const std::string & table_name,
ColumnsDescription cached_columns) const override; ColumnsDescription cached_columns,
bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "S3"; } const char * getStorageTypeName() const override { return "S3"; }
ColumnsDescription getActualTableStructure(ContextPtr context) const override; ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
void parseArguments(const ASTPtr & ast_function, ContextPtr context) override; void parseArguments(const ASTPtr & ast_function, ContextPtr context) override;
mutable StorageS3::Configuration configuration; mutable StorageS3::Configuration configuration;

View File

@ -17,7 +17,7 @@ namespace DB
StoragePtr TableFunctionS3Cluster::executeImpl( StoragePtr TableFunctionS3Cluster::executeImpl(
const ASTPtr & /*function*/, ContextPtr context, const ASTPtr & /*function*/, ContextPtr context,
const std::string & table_name, ColumnsDescription /*cached_columns*/) const const std::string & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
StoragePtr storage; StoragePtr storage;
ColumnsDescription columns; ColumnsDescription columns;

View File

@ -52,7 +52,8 @@ protected:
const ASTPtr & ast_function, const ASTPtr & ast_function,
ContextPtr context, ContextPtr context,
const std::string & table_name, const std::string & table_name,
ColumnsDescription cached_columns) const override; ColumnsDescription cached_columns,
bool is_insert_query) const override;
const char * getStorageTypeName() const override { return "S3Cluster"; } const char * getStorageTypeName() const override { return "S3Cluster"; }
}; };

View File

@ -29,7 +29,7 @@ namespace ErrorCodes
StoragePtr TableFunctionSQLite::executeImpl(const ASTPtr & /*ast_function*/, StoragePtr TableFunctionSQLite::executeImpl(const ASTPtr & /*ast_function*/,
ContextPtr context, const String & table_name, ColumnsDescription /*cached_columns*/) const ContextPtr context, const String & table_name, ColumnsDescription /*cached_columns*/, bool /*is_insert_query*/) const
{ {
auto storage = std::make_shared<StorageSQLite>(StorageID(getDatabaseName(), table_name), auto storage = std::make_shared<StorageSQLite>(StorageID(getDatabaseName(), table_name),
sqlite_db, sqlite_db,
@ -42,7 +42,7 @@ StoragePtr TableFunctionSQLite::executeImpl(const ASTPtr & /*ast_function*/,
} }
ColumnsDescription TableFunctionSQLite::getActualTableStructure(ContextPtr /* context */) const ColumnsDescription TableFunctionSQLite::getActualTableStructure(ContextPtr /* context */, bool /*is_insert_query*/) const
{ {
return StorageSQLite::getTableStructureFromData(sqlite_db, remote_table_name); return StorageSQLite::getTableStructureFromData(sqlite_db, remote_table_name);
} }

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