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>
|
|
|
|
#include <Interpreters/InterpreterWatchQuery.h>
|
2020-05-20 20:16:32 +00:00
|
|
|
#include <Interpreters/Context.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-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;
|
|
|
|
res.pipeline = QueryPipelineBuilder::getPipeline(buildQueryPipeline());
|
|
|
|
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)
|
2020-02-17 19:28:25 +00:00
|
|
|
throw Exception("Table " + table_id.getNameForLogs() + " doesn't exist.",
|
2019-05-30 21:29:30 +00:00
|
|
|
ErrorCodes::UNKNOWN_TABLE);
|
|
|
|
|
2021-11-20 15:34:45 +00:00
|
|
|
auto storage_name = storage->getName();
|
|
|
|
if (storage_name == "LiveView"
|
|
|
|
&& !getContext()->getSettingsRef().allow_experimental_live_view)
|
|
|
|
throw Exception("Experimental LIVE VIEW feature is not enabled (the setting 'allow_experimental_live_view')",
|
|
|
|
ErrorCodes::SUPPORT_IS_DISABLED);
|
|
|
|
else if (storage_name == "WindowView"
|
|
|
|
&& !getContext()->getSettingsRef().allow_experimental_window_view)
|
|
|
|
throw Exception("Experimental WINDOW VIEW feature is not enabled (the setting 'allow_experimental_window_view')",
|
|
|
|
ErrorCodes::SUPPORT_IS_DISABLED);
|
|
|
|
|
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)
|
|
|
|
throw Exception("Limit for number of columns to read exceeded. "
|
|
|
|
"Requested: " + std::to_string(required_columns.size())
|
|
|
|
+ ", maximum: " + settings.max_columns_to_read.toString(),
|
|
|
|
ErrorCodes::TOO_MANY_COLUMNS);
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
/// Constraints on the result, the quota on the result, and also callback for progress.
|
|
|
|
{
|
2020-09-15 10:40:39 +00:00
|
|
|
StreamLocalLimits limits;
|
2021-05-08 16:09:17 +00:00
|
|
|
limits.mode = LimitsMode::LIMITS_CURRENT; //-V1048
|
2020-02-02 20:59:18 +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;
|
|
|
|
|
2021-08-11 17:28:54 +00:00
|
|
|
pipe.setLimits(limits);
|
|
|
|
pipe.setQuota(getContext()->getQuota());
|
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
|
|
|
}
|
|
|
|
|
|
|
|
}
|