diff --git a/src/Analyzer/Passes/QueryAnalysisPass.cpp b/src/Analyzer/Passes/QueryAnalysisPass.cpp index 7ab0261850b..aa915e48d35 100644 --- a/src/Analyzer/Passes/QueryAnalysisPass.cpp +++ b/src/Analyzer/Passes/QueryAnalysisPass.cpp @@ -6355,7 +6355,7 @@ void QueryAnalyzer::resolveTableFunction(QueryTreeNodePtr & table_function_node, auto table_function_ast = table_function_node_typed.toAST(); table_function_ptr->parseArguments(table_function_ast, scope_context); - auto table_function_storage = table_function_ptr->execute(table_function_ast, scope_context, table_function_ptr->getName()); + 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); } diff --git a/src/Interpreters/Context.cpp b/src/Interpreters/Context.cpp index d9f450191bc..62573fb18a7 100644 --- a/src/Interpreters/Context.cpp +++ b/src/Interpreters/Context.cpp @@ -1623,6 +1623,31 @@ StoragePtr Context::executeTableFunction(const ASTPtr & table_expression, const return res; } +StoragePtr Context::executeTableFunction(const ASTPtr & table_expression, const TableFunctionPtr & table_function_ptr) +{ + auto hash = table_expression->getTreeHash(); + String key = toString(hash.first) + '_' + toString(hash.second); + StoragePtr & res = table_function_results[key]; + + if (!res) + { + res = table_function_ptr->execute(table_expression, shared_from_this(), table_function_ptr->getName()); + + /// Since ITableFunction::parseArguments() may change table_expression, i.e.: + /// + /// remote('127.1', system.one) -> remote('127.1', 'system.one'), + /// + auto new_hash = table_expression->getTreeHash(); + if (hash != new_hash) + { + key = toString(new_hash.first) + '_' + toString(new_hash.second); + table_function_results[key] = res; + } + } + + return res; +} + void Context::addViewSource(const StoragePtr & storage) { diff --git a/src/Interpreters/Context.h b/src/Interpreters/Context.h index 1be662e0958..3862984bb6f 100644 --- a/src/Interpreters/Context.h +++ b/src/Interpreters/Context.h @@ -108,6 +108,7 @@ class StorageS3Settings; class IDatabase; class DDLWorker; class ITableFunction; +using TableFunctionPtr = std::shared_ptr; class Block; class ActionLocksManager; using ActionLocksManagerPtr = std::shared_ptr; @@ -650,6 +651,8 @@ public: /// For table functions s3/file/url/hdfs/input we can use structure from /// insertion table depending on select expression. StoragePtr executeTableFunction(const ASTPtr & table_expression, const ASTSelectQuery * select_query_hint = nullptr); + /// Overload for the new analyzer. Structure inference is performed in QueryAnalysisPass. + StoragePtr executeTableFunction(const ASTPtr & table_expression, const TableFunctionPtr & table_function_ptr); void addViewSource(const StoragePtr & storage); StoragePtr getViewSource() const;