same fix for analyzer

This commit is contained in:
Yakov Olkhovskiy 2023-03-24 13:16:54 +00:00
parent 3e50ccdb45
commit 83ca006fcb

View File

@ -6097,25 +6097,9 @@ void QueryAnalyzer::resolveTableFunction(QueryTreeNodePtr & table_function_node,
if (!nested_table_function)
expressions_visitor.visit(table_function_node_typed.getArgumentsNode());
const auto & table_function_factory = TableFunctionFactory::instance();
const auto & table_function_name = table_function_node_typed.getTableFunctionName();
auto & scope_context = scope.context;
TableFunctionPtr table_function_ptr = table_function_factory.tryGet(table_function_name, scope_context);
if (!table_function_ptr)
{
auto hints = TableFunctionFactory::instance().getHints(table_function_name);
if (!hints.empty())
throw Exception(ErrorCodes::UNKNOWN_FUNCTION,
"Unknown table function {}. Maybe you meant: {}",
table_function_name,
DB::toString(hints));
else
throw Exception(ErrorCodes::UNKNOWN_FUNCTION,
"Unknown table function {}",
table_function_name);
}
TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_function_node_typed.toAST(), scope_context);
if (!nested_table_function &&
scope_context->getSettingsRef().use_structure_from_insertion_table_in_table_functions &&
@ -6125,9 +6109,40 @@ void QueryAnalyzer::resolveTableFunction(QueryTreeNodePtr & table_function_node,
const auto & insertion_table = scope_context->getInsertionTable();
if (!insertion_table.empty())
{
auto insertion_table_storage = DatabaseCatalog::instance().getTable(insertion_table, scope_context);
const auto & structure_hint = insertion_table_storage->getInMemoryMetadataPtr()->columns;
table_function_ptr->setStructureHint(structure_hint);
auto & expression_list = scope.scope_node->as<QueryNode &>().getProjection();
const auto & insert_structure = DatabaseCatalog::instance().getTable(insertion_table, scope_context)->getInMemoryMetadataPtr()->getColumns();
auto table_structure = table_function_ptr->getActualTableStructure(scope_context);
/// Insert table matches columns against SELECT expression by position, so we want to map
/// insert table columns to table function columns through names from SELECT expression.
auto insert_column = insert_structure.begin();
for (const auto & expression : expression_list)
{
if (auto * identifier_node = expression->as<IdentifierNode>())
{
if (table_structure.hasPhysical(identifier_node->getIdentifier().getFullName()))
table_structure.modify(identifier_node->getIdentifier().getFullName(), [&insert_column](ColumnDescription & column){ column.type = insert_column->type; });
++insert_column;
}
else if (auto * matcher_node = expression->as<MatcherNode>(); matcher_node && matcher_node->getMatcherType() == MatcherNodeType::ASTERISK)
{
for (const auto & column : table_structure)
{
table_structure.modify(column.name, [&insert_column](ColumnDescription & column){ column.type = insert_column->type; });
++insert_column;
if (insert_column == insert_structure.end())
break;
}
}
else
++insert_column;
if (insert_column == insert_structure.end())
break;
}
table_function_ptr->setStructureHint(table_structure);
}
}