@@ -57,18 +57,13 @@ class TableFunctionMerge : public ITableFunction
5757 StoragePtr executeImpl (const ASTPtr & ast_function, ContextPtr context, const std::string & table_name, ColumnsDescription cached_columns, bool is_insert_query) const override ;
5858 const char * getStorageTypeName () const override { return " Merge" ; }
5959
60- using TableSet = std::set<String>;
61- using DBToTableSetMap = std::map<String, TableSet>;
62- const DBToTableSetMap & getSourceDatabasesAndTables (ContextPtr context) const ;
6360 ColumnsDescription getActualTableStructure (ContextPtr context, bool is_insert_query) const override ;
6461 std::vector<size_t > skipAnalysisForArguments (const QueryTreeNodePtr & query_node_table_function, ContextPtr context) const override ;
6562 void parseArguments (const ASTPtr & ast_function, ContextPtr context) override ;
66- static TableSet getMatchedTablesWithAccess (const String & database_name, const String & table_regexp, const ContextPtr & context);
6763
6864 String source_database_name_or_regexp;
6965 String source_table_regexp;
7066 bool database_is_regexp = false ;
71- mutable std::optional<DBToTableSetMap> source_databases_and_tables;
7267};
7368
7469std::vector<size_t > TableFunctionMerge::skipAnalysisForArguments (const QueryTreeNodePtr & query_node_table_function, ContextPtr) const
@@ -129,63 +124,18 @@ void TableFunctionMerge::parseArguments(const ASTPtr & ast_function, ContextPtr
129124 }
130125}
131126
132-
133- const TableFunctionMerge::DBToTableSetMap & TableFunctionMerge::getSourceDatabasesAndTables (ContextPtr context) const
134- {
135- if (source_databases_and_tables)
136- return *source_databases_and_tables;
137-
138- source_databases_and_tables.emplace ();
139-
140- // / database_name is not a regexp
141- if (!database_is_regexp)
142- {
143- auto source_tables = getMatchedTablesWithAccess (source_database_name_or_regexp, source_table_regexp, context);
144- if (source_tables.empty ())
145- throwNoTablesMatchRegexp (source_database_name_or_regexp, source_table_regexp);
146- (*source_databases_and_tables)[source_database_name_or_regexp] = source_tables;
147- }
148-
149- // / database_name is a regexp
150- else
151- {
152- OptimizedRegularExpression database_re (source_database_name_or_regexp);
153- auto databases = DatabaseCatalog::instance ().getDatabases ();
154-
155- for (const auto & db : databases)
156- if (database_re.match (db.first ))
157- (*source_databases_and_tables)[db.first ] = getMatchedTablesWithAccess (db.first , source_table_regexp, context);
158-
159- if (source_databases_and_tables->empty ())
160- throwNoTablesMatchRegexp (source_database_name_or_regexp, source_table_regexp);
161- }
162-
163- return *source_databases_and_tables;
164- }
165-
166127ColumnsDescription TableFunctionMerge::getActualTableStructure (ContextPtr context, bool /* is_insert_query*/ ) const
167128{
168- size_t table_num = 0 ;
169- size_t max_tables_to_look = context->getSettingsRef ()[Setting::merge_table_max_tables_to_look_for_schema_inference];
129+ auto res = StorageMerge::getColumnsDescriptionFromSourceTables (
130+ context,
131+ source_database_name_or_regexp,
132+ database_is_regexp,
133+ source_table_regexp,
134+ context->getSettingsRef ()[Setting::merge_table_max_tables_to_look_for_schema_inference]);
135+ if (res.empty ())
136+ throwNoTablesMatchRegexp (source_database_name_or_regexp, source_table_regexp);
170137
171- return StorageMerge::unifyColumnsDescription ([&table_num, &context, max_tables_to_look, this ](std::function<void (const StoragePtr &)> callback)
172- {
173- for (const auto & db_with_tables : getSourceDatabasesAndTables (context))
174- {
175- for (const auto & table : db_with_tables.second )
176- {
177- if (table_num >= max_tables_to_look)
178- return ;
179-
180- auto storage = DatabaseCatalog::instance ().tryGetTable (StorageID{db_with_tables.first , table}, context);
181- if (storage)
182- {
183- ++table_num;
184- callback (storage);
185- }
186- }
187- }
188- });
138+ return res;
189139}
190140
191141
@@ -197,43 +147,13 @@ StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & /*ast_function*/, Cont
197147 String{},
198148 source_database_name_or_regexp,
199149 database_is_regexp,
200- getSourceDatabasesAndTables (context) ,
150+ source_table_regexp ,
201151 context);
202152
203153 res->startup ();
204154 return res;
205155}
206156
207- TableFunctionMerge::TableSet
208- TableFunctionMerge::getMatchedTablesWithAccess (const String & database_name, const String & table_regexp, const ContextPtr & context)
209- {
210- OptimizedRegularExpression table_re (table_regexp);
211-
212- auto table_name_match = [&](const String & table_name) { return table_re.match (table_name); };
213-
214- auto access = context->getAccess ();
215-
216- auto database = DatabaseCatalog::instance ().getDatabase (database_name);
217-
218- bool granted_show_on_all_tables = access->isGranted (AccessType::SHOW_TABLES, database_name);
219- bool granted_select_on_all_tables = access->isGranted (AccessType::SELECT, database_name);
220-
221- TableSet tables;
222-
223- for (auto it = database->getTablesIterator (context, table_name_match); it->isValid (); it->next ())
224- {
225- if (!it->table ())
226- continue ;
227- bool granted_show = granted_show_on_all_tables || access->isGranted (AccessType::SHOW_TABLES, database_name, it->name ());
228- if (!granted_show)
229- continue ;
230- if (!granted_select_on_all_tables)
231- access->checkAccess (AccessType::SELECT, database_name, it->name ());
232- tables.emplace (it->name ());
233- }
234- return tables;
235- }
236-
237157}
238158
239159void registerTableFunctionMerge (TableFunctionFactory & factory)
0 commit comments