2019-05-26 22:03:30 +00:00
|
|
|
/* Copyright (c) 2018 BlackBerry Limited
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License. */
|
|
|
|
#include <Core/Settings.h>
|
|
|
|
#include <Common/typeid_cast.h>
|
|
|
|
#include <Parsers/ASTWatchQuery.h>
|
2024-03-19 16:04:29 +00:00
|
|
|
#include <Interpreters/Context.h>
|
|
|
|
#include <Interpreters/DatabaseCatalog.h>
|
2024-01-09 06:33:48 +00:00
|
|
|
#include <Interpreters/InterpreterFactory.h>
|
2019-05-26 22:03:30 +00:00
|
|
|
#include <Interpreters/InterpreterWatchQuery.h>
|
2021-10-31 08:51:20 +00:00
|
|
|
#include <Access/Common/AccessFlags.h>
|
2021-10-15 20:18:20 +00:00
|
|
|
#include <QueryPipeline/StreamLocalLimits.h>
|
2022-05-20 19:49:31 +00:00
|
|
|
#include <QueryPipeline/QueryPipelineBuilder.h>
|
2022-01-10 19:01:41 +00:00
|
|
|
#include <Storages/IStorage.h>
|
2019-05-26 22:03:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
2019-05-30 21:29:30 +00:00
|
|
|
extern const int UNKNOWN_TABLE;
|
2019-05-26 22:03:30 +00:00
|
|
|
extern const int TOO_MANY_COLUMNS;
|
2019-08-22 23:46:40 +00:00
|
|
|
extern const int SUPPORT_IS_DISABLED;
|
2019-05-26 22:03:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BlockIO InterpreterWatchQuery::execute()
|
2021-09-16 17:40:42 +00:00
|
|
|
{
|
|
|
|
BlockIO res;
|
2022-05-24 20:06:08 +00:00
|
|
|
res.pipeline = QueryPipelineBuilder::getPipeline(buildQueryPipeline());
|
2022-05-20 19:49:31 +00:00
|
|
|
|
|
|
|
/// Constraints on the result, the quota on the result, and also callback for progress.
|
|
|
|
{
|
|
|
|
const Settings & settings = getContext()->getSettingsRef();
|
|
|
|
|
|
|
|
StreamLocalLimits limits;
|
2023-02-19 22:15:09 +00:00
|
|
|
limits.mode = LimitsMode::LIMITS_CURRENT;
|
2022-05-20 19:49:31 +00:00
|
|
|
limits.size_limits.max_rows = settings.max_result_rows;
|
|
|
|
limits.size_limits.max_bytes = settings.max_result_bytes;
|
|
|
|
limits.size_limits.overflow_mode = settings.result_overflow_mode;
|
|
|
|
|
2022-05-31 14:43:38 +00:00
|
|
|
res.pipeline.setLimitsAndQuota(limits, getContext()->getQuota());
|
2022-05-20 19:49:31 +00:00
|
|
|
}
|
|
|
|
|
2021-09-16 17:40:42 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryPipelineBuilder InterpreterWatchQuery::buildQueryPipeline()
|
2019-05-26 22:03:30 +00:00
|
|
|
{
|
|
|
|
const ASTWatchQuery & query = typeid_cast<const ASTWatchQuery &>(*query_ptr);
|
2021-04-10 23:33:54 +00:00
|
|
|
auto table_id = getContext()->resolveStorageID(query, Context::ResolveOrdinary);
|
2019-05-26 22:03:30 +00:00
|
|
|
|
|
|
|
/// Get storage
|
2021-04-10 23:33:54 +00:00
|
|
|
storage = DatabaseCatalog::instance().tryGetTable(table_id, getContext());
|
2019-05-26 22:03:30 +00:00
|
|
|
|
2019-05-30 21:29:30 +00:00
|
|
|
if (!storage)
|
2023-12-26 11:53:00 +00:00
|
|
|
throw Exception(ErrorCodes::UNKNOWN_TABLE, "Table {} does not exist.", table_id.getNameForLogs());
|
2019-05-30 21:29:30 +00:00
|
|
|
|
2021-11-20 15:34:45 +00:00
|
|
|
auto storage_name = storage->getName();
|
|
|
|
if (storage_name == "LiveView"
|
|
|
|
&& !getContext()->getSettingsRef().allow_experimental_live_view)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED,
|
|
|
|
"Experimental LIVE VIEW feature is not enabled (the setting 'allow_experimental_live_view')");
|
2021-11-20 15:34:45 +00:00
|
|
|
else if (storage_name == "WindowView"
|
|
|
|
&& !getContext()->getSettingsRef().allow_experimental_window_view)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED,
|
|
|
|
"Experimental WINDOW VIEW feature is not enabled (the setting 'allow_experimental_window_view')");
|
2021-11-20 15:34:45 +00:00
|
|
|
|
2019-05-26 22:03:30 +00:00
|
|
|
/// List of columns to read to execute the query.
|
2020-06-17 16:39:58 +00:00
|
|
|
Names required_columns = storage->getInMemoryMetadataPtr()->getColumns().getNamesOfPhysical();
|
2021-04-10 23:33:54 +00:00
|
|
|
getContext()->checkAccess(AccessType::SELECT, table_id, required_columns);
|
2019-05-26 22:03:30 +00:00
|
|
|
|
|
|
|
/// Get context settings for this query
|
2021-04-10 23:33:54 +00:00
|
|
|
const Settings & settings = getContext()->getSettingsRef();
|
2019-05-26 22:03:30 +00:00
|
|
|
|
|
|
|
/// Limitation on the number of columns to read.
|
|
|
|
if (settings.max_columns_to_read && required_columns.size() > settings.max_columns_to_read)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::TOO_MANY_COLUMNS, "Limit for number of columns to read exceeded. "
|
|
|
|
"Requested: {}, maximum: {}", required_columns.size(), settings.max_columns_to_read.toString());
|
2019-05-26 22:03:30 +00:00
|
|
|
|
|
|
|
size_t max_block_size = settings.max_block_size;
|
|
|
|
size_t max_streams = 1;
|
|
|
|
|
|
|
|
/// Define query info
|
|
|
|
SelectQueryInfo query_info;
|
|
|
|
query_info.query = query_ptr;
|
|
|
|
|
|
|
|
/// From stage
|
|
|
|
QueryProcessingStage::Enum from_stage = QueryProcessingStage::FetchColumns;
|
|
|
|
|
|
|
|
/// Watch storage
|
2021-08-11 17:28:54 +00:00
|
|
|
auto pipe = storage->watch(required_columns, query_info, getContext(), from_stage, max_block_size, max_streams);
|
2019-05-26 22:03:30 +00:00
|
|
|
|
2021-09-16 17:40:42 +00:00
|
|
|
QueryPipelineBuilder pipeline;
|
|
|
|
pipeline.init(std::move(pipe));
|
|
|
|
return pipeline;
|
2019-05-26 22:03:30 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 06:33:48 +00:00
|
|
|
void registerInterpreterWatchQuery(InterpreterFactory & factory)
|
|
|
|
{
|
|
|
|
auto create_fn = [] (const InterpreterFactory::Arguments & args)
|
|
|
|
{
|
|
|
|
return std::make_unique<InterpreterWatchQuery>(args.query, args.context);
|
|
|
|
};
|
|
|
|
factory.registerInterpreter("InterpreterWatchQuery", create_fn);
|
|
|
|
}
|
|
|
|
|
2019-05-26 22:03:30 +00:00
|
|
|
}
|