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; }; }