From 5b11d72ce4cadd3f4d4e13c0bcdc50049a5b7ff4 Mon Sep 17 00:00:00 2001 From: Smita Kulkarni Date: Sat, 11 Mar 2023 20:39:43 +0100 Subject: [PATCH] In parameterized view, moved parameter values to SelectQueryInfo from StorageView as it can be used by multiple queries and updated column name check to avoid issues with parameter name being substring of column name. --- src/Interpreters/InterpreterSelectQuery.cpp | 9 ++++----- src/Storages/SelectQueryInfo.h | 1 + src/Storages/StorageView.cpp | 10 ++++++---- src/Storages/StorageView.h | 14 ++++---------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index 2f579244b9a..20400b0e48b 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -575,14 +575,13 @@ InterpreterSelectQuery::InterpreterSelectQuery( /// and after query is replaced, we use these parameters to substitute in the parameterized view query if (query_info.is_parameterized_view) { - parameter_values = analyzeFunctionParamValues(query_ptr); - view->setParameterValues(parameter_values); - parameter_types = view->getParameterValues(); + query_info.parameter_values = analyzeFunctionParamValues(query_ptr); + parameter_types = view->getParameterTypes(); } view->replaceWithSubquery(getSelectQuery(), view_table, metadata_snapshot, view->isParameterizedView()); if (query_info.is_parameterized_view) { - view->replaceQueryParametersIfParametrizedView(query_ptr); + view->replaceQueryParametersIfParametrizedView(query_ptr, query_info.parameter_values); } } @@ -595,7 +594,7 @@ InterpreterSelectQuery::InterpreterSelectQuery( required_result_column_names, table_join, query_info.is_parameterized_view, - parameter_values, + query_info.parameter_values, parameter_types); diff --git a/src/Storages/SelectQueryInfo.h b/src/Storages/SelectQueryInfo.h index e3996950e79..db43b2fc3f8 100644 --- a/src/Storages/SelectQueryInfo.h +++ b/src/Storages/SelectQueryInfo.h @@ -254,6 +254,7 @@ struct SelectQueryInfo MergeTreeDataSelectAnalysisResultPtr merge_tree_select_result_ptr; bool is_parameterized_view = false; + NameToNameMap parameterized_view_values; // If limit is not 0, that means it's a trivial limit query. UInt64 limit = 0; diff --git a/src/Storages/StorageView.cpp b/src/Storages/StorageView.cpp index 1a7050b4dff..d1595895f67 100644 --- a/src/Storages/StorageView.cpp +++ b/src/Storages/StorageView.cpp @@ -36,6 +36,7 @@ namespace ErrorCodes extern const int LOGICAL_ERROR; } + namespace { @@ -118,7 +119,7 @@ StorageView::StorageView( description.inner_query = query.select->ptr(); is_parameterized_view = query.isParameterizedView(); - parameter_types = analyzeReceiveQueryParamsWithType(description.inner_query); + view_parameter_types = analyzeReceiveQueryParamsWithType(description.inner_query); storage_metadata.setSelectQuery(description); setInMemoryMetadata(storage_metadata); } @@ -167,7 +168,7 @@ void StorageView::read( query_plan.addStep(std::move(materializing)); /// And also convert to expected structure. - const auto & expected_header = storage_snapshot->getSampleBlockForColumns(column_names,parameter_values); + const auto & expected_header = storage_snapshot->getSampleBlockForColumns(column_names,query_info.parameter_values); const auto & header = query_plan.getCurrentDataStream().header; const auto * select_with_union = current_inner_query->as(); @@ -203,7 +204,7 @@ static ASTTableExpression * getFirstTableExpression(ASTSelectQuery & select_quer return select_element->table_expression->as(); } -void StorageView::replaceQueryParametersIfParametrizedView(ASTPtr & outer_query) +void StorageView::replaceQueryParametersIfParametrizedView(ASTPtr & outer_query, const NameToNameMap & parameter_values) { ReplaceQueryParameterVisitor visitor(parameter_values); visitor.visit(outer_query); @@ -261,7 +262,8 @@ String StorageView::replaceQueryParameterWithValue(const String & column_name, c if ((pos = name.find(parameter.first)) != std::string::npos) { auto parameter_datatype_iterator = parameter_types.find(parameter.first); - if (parameter_datatype_iterator != parameter_types.end()) + size_t parameter_end = pos+parameter.first.size(); + if (parameter_datatype_iterator != parameter_types.end() && name.size() >= parameter_end && (name[parameter_end]==',' || name[parameter_end]==')')) { String parameter_name("_CAST(" + parameter.second + ", '" + parameter_datatype_iterator->second + "')"); name.replace(pos, parameter.first.size(), parameter_name); diff --git a/src/Storages/StorageView.h b/src/Storages/StorageView.h index 6cd4bb171f5..d7ee9b664d6 100644 --- a/src/Storages/StorageView.h +++ b/src/Storages/StorageView.h @@ -35,7 +35,7 @@ public: size_t max_block_size, size_t num_streams) override; - void replaceQueryParametersIfParametrizedView(ASTPtr & outer_query); + void replaceQueryParametersIfParametrizedView(ASTPtr & outer_query, const NameToNameMap & parameter_values); static void replaceWithSubquery(ASTSelectQuery & select_query, ASTPtr & view_name, const StorageMetadataPtr & metadata_snapshot, const bool parameterized_view) { @@ -47,20 +47,14 @@ public: static String replaceQueryParameterWithValue (const String & column_name, const NameToNameMap & parameter_values, const NameToNameMap & parameter_types); static String replaceValueWithQueryParameter (const String & column_name, const NameToNameMap & parameter_values); - void setParameterValues (NameToNameMap parameter_values_) + NameToNameMap getParameterTypes() const { - parameter_values = parameter_values_; - } - - NameToNameMap getParameterValues() const - { - return parameter_types; + return view_parameter_types; } protected: bool is_parameterized_view; - NameToNameMap parameter_values; - NameToNameMap parameter_types; + NameToNameMap view_parameter_types; }; }