From ae05f4f604e2eead6ac4bbe41d30cb06b3784cd7 Mon Sep 17 00:00:00 2001 From: avogar Date: Mon, 13 Nov 2023 21:35:15 +0000 Subject: [PATCH] Fix use_structure_from_insertion_table_in_table_functions with new Analyzer --- src/Analyzer/Passes/QueryAnalysisPass.cpp | 175 +++++++++++----------- 1 file changed, 88 insertions(+), 87 deletions(-) diff --git a/src/Analyzer/Passes/QueryAnalysisPass.cpp b/src/Analyzer/Passes/QueryAnalysisPass.cpp index 7855c4f34a8..d6c9c7ab807 100644 --- a/src/Analyzer/Passes/QueryAnalysisPass.cpp +++ b/src/Analyzer/Passes/QueryAnalysisPass.cpp @@ -6327,6 +6327,94 @@ void QueryAnalyzer::resolveTableFunction(QueryTreeNodePtr & table_function_node, table_function_name); } + QueryTreeNodes result_table_function_arguments; + + auto skip_analysis_arguments_indexes = table_function_ptr->skipAnalysisForArguments(table_function_node, scope_context); + + auto & table_function_arguments = table_function_node_typed.getArguments().getNodes(); + size_t table_function_arguments_size = table_function_arguments.size(); + + for (size_t table_function_argument_index = 0; table_function_argument_index < table_function_arguments_size; ++table_function_argument_index) + { + auto & table_function_argument = table_function_arguments[table_function_argument_index]; + + auto skip_argument_index_it = std::find(skip_analysis_arguments_indexes.begin(), + skip_analysis_arguments_indexes.end(), + table_function_argument_index); + if (skip_argument_index_it != skip_analysis_arguments_indexes.end()) + { + result_table_function_arguments.push_back(table_function_argument); + continue; + } + + if (auto * identifier_node = table_function_argument->as()) + { + const auto & unresolved_identifier = identifier_node->getIdentifier(); + auto identifier_resolve_result = tryResolveIdentifier({unresolved_identifier, IdentifierLookupContext::EXPRESSION}, scope); + auto resolved_identifier = std::move(identifier_resolve_result.resolved_identifier); + + if (resolved_identifier && resolved_identifier->getNodeType() == QueryTreeNodeType::CONSTANT) + result_table_function_arguments.push_back(std::move(resolved_identifier)); + else + result_table_function_arguments.push_back(table_function_argument); + + continue; + } + else if (auto * table_function_argument_function = table_function_argument->as()) + { + const auto & table_function_argument_function_name = table_function_argument_function->getFunctionName(); + if (TableFunctionFactory::instance().isTableFunctionName(table_function_argument_function_name)) + { + auto table_function_node_to_resolve_typed = std::make_shared(table_function_argument_function_name); + table_function_node_to_resolve_typed->getArgumentsNode() = table_function_argument_function->getArgumentsNode(); + + QueryTreeNodePtr table_function_node_to_resolve = std::move(table_function_node_to_resolve_typed); + resolveTableFunction(table_function_node_to_resolve, scope, expressions_visitor, true /*nested_table_function*/); + + result_table_function_arguments.push_back(std::move(table_function_node_to_resolve)); + continue; + } + } + + /** Table functions arguments can contain expressions with invalid identifiers. + * We cannot skip analysis for such arguments, because some table functions cannot provide + * information if analysis for argument should be skipped until other arguments will be resolved. + * + * Example: SELECT key from remote('127.0.0.{1,2}', view(select number AS key from numbers(2)), cityHash64(key)); + * Example: SELECT id from remote('127.0.0.{1,2}', 'default', 'test_table', cityHash64(id)); + */ + try + { + resolveExpressionNode(table_function_argument, scope, false /*allow_lambda_expression*/, false /*allow_table_expression*/); + } + catch (const Exception & exception) + { + if (exception.code() == ErrorCodes::UNKNOWN_IDENTIFIER) + { + result_table_function_arguments.push_back(table_function_argument); + continue; + } + + throw; + } + + if (auto * expression_list = table_function_argument->as()) + { + for (auto & expression_list_node : expression_list->getNodes()) + result_table_function_arguments.push_back(expression_list_node); + } + else + { + result_table_function_arguments.push_back(table_function_argument); + } + } + + table_function_node_typed.getArguments().getNodes() = std::move(result_table_function_arguments); + + auto table_function_ast = table_function_node_typed.toAST(); + table_function_ptr->parseArguments(table_function_ast, scope_context); + + uint64_t use_structure_from_insertion_table_in_table_functions = scope_context->getSettingsRef().use_structure_from_insertion_table_in_table_functions; if (!nested_table_function && use_structure_from_insertion_table_in_table_functions && @@ -6468,93 +6556,6 @@ void QueryAnalyzer::resolveTableFunction(QueryTreeNodePtr & table_function_node, } } - QueryTreeNodes result_table_function_arguments; - - auto skip_analysis_arguments_indexes = table_function_ptr->skipAnalysisForArguments(table_function_node, scope_context); - - auto & table_function_arguments = table_function_node_typed.getArguments().getNodes(); - size_t table_function_arguments_size = table_function_arguments.size(); - - for (size_t table_function_argument_index = 0; table_function_argument_index < table_function_arguments_size; ++table_function_argument_index) - { - auto & table_function_argument = table_function_arguments[table_function_argument_index]; - - auto skip_argument_index_it = std::find(skip_analysis_arguments_indexes.begin(), - skip_analysis_arguments_indexes.end(), - table_function_argument_index); - if (skip_argument_index_it != skip_analysis_arguments_indexes.end()) - { - result_table_function_arguments.push_back(table_function_argument); - continue; - } - - if (auto * identifier_node = table_function_argument->as()) - { - const auto & unresolved_identifier = identifier_node->getIdentifier(); - auto identifier_resolve_result = tryResolveIdentifier({unresolved_identifier, IdentifierLookupContext::EXPRESSION}, scope); - auto resolved_identifier = std::move(identifier_resolve_result.resolved_identifier); - - if (resolved_identifier && resolved_identifier->getNodeType() == QueryTreeNodeType::CONSTANT) - result_table_function_arguments.push_back(std::move(resolved_identifier)); - else - result_table_function_arguments.push_back(table_function_argument); - - continue; - } - else if (auto * table_function_argument_function = table_function_argument->as()) - { - const auto & table_function_argument_function_name = table_function_argument_function->getFunctionName(); - if (TableFunctionFactory::instance().isTableFunctionName(table_function_argument_function_name)) - { - auto table_function_node_to_resolve_typed = std::make_shared(table_function_argument_function_name); - table_function_node_to_resolve_typed->getArgumentsNode() = table_function_argument_function->getArgumentsNode(); - - QueryTreeNodePtr table_function_node_to_resolve = std::move(table_function_node_to_resolve_typed); - resolveTableFunction(table_function_node_to_resolve, scope, expressions_visitor, true /*nested_table_function*/); - - result_table_function_arguments.push_back(std::move(table_function_node_to_resolve)); - continue; - } - } - - /** Table functions arguments can contain expressions with invalid identifiers. - * We cannot skip analysis for such arguments, because some table functions cannot provide - * information if analysis for argument should be skipped until other arguments will be resolved. - * - * Example: SELECT key from remote('127.0.0.{1,2}', view(select number AS key from numbers(2)), cityHash64(key)); - * Example: SELECT id from remote('127.0.0.{1,2}', 'default', 'test_table', cityHash64(id)); - */ - try - { - resolveExpressionNode(table_function_argument, scope, false /*allow_lambda_expression*/, false /*allow_table_expression*/); - } - catch (const Exception & exception) - { - if (exception.code() == ErrorCodes::UNKNOWN_IDENTIFIER) - { - result_table_function_arguments.push_back(table_function_argument); - continue; - } - - throw; - } - - if (auto * expression_list = table_function_argument->as()) - { - for (auto & expression_list_node : expression_list->getNodes()) - result_table_function_arguments.push_back(expression_list_node); - } - else - { - result_table_function_arguments.push_back(table_function_argument); - } - } - - table_function_node_typed.getArguments().getNodes() = std::move(result_table_function_arguments); - - auto table_function_ast = table_function_node_typed.toAST(); - table_function_ptr->parseArguments(table_function_ast, scope_context); - auto table_function_storage = scope_context->getQueryContext()->executeTableFunction(table_function_ast, table_function_ptr); table_function_node_typed.resolve(std::move(table_function_ptr), std::move(table_function_storage), scope_context, std::move(skip_analysis_arguments_indexes)); }