| 431 | } |
| 432 | |
| 433 | void ShellState::RenderTableMetadata(vector<ShellTableInfo> &tables) { |
| 434 | idx_t max_render_width = GetMaxRenderWidth(); |
| 435 | duckdb::BoxRendererConfig config; |
| 436 | // figure out the render width of each table |
| 437 | vector<ShellTableRenderInfo> table_list; |
| 438 | for (auto &table : tables) { |
| 439 | table_list.emplace_back(table, config.decimal_separator); |
| 440 | } |
| 441 | for (auto &table : table_list) { |
| 442 | // optionally truncate each table if we exceed the max render width |
| 443 | table.Truncate(max_render_width); |
| 444 | } |
| 445 | // try to split up large tables |
| 446 | for (auto &table : table_list) { |
| 447 | static constexpr const idx_t SPLIT_THRESHOLD = 20; |
| 448 | D_ASSERT(table.column_renders.size() == 1); |
| 449 | if (table.column_renders[0].columns.size() <= SPLIT_THRESHOLD) { |
| 450 | // not that many columns - keep it as-is |
| 451 | continue; |
| 452 | } |
| 453 | // try to split up columns if possible |
| 454 | idx_t max_split_count = (table.column_renders[0].columns.size() + SPLIT_THRESHOLD - 1) / SPLIT_THRESHOLD; |
| 455 | idx_t width_per_split = table.PerColumnWidth(); |
| 456 | idx_t max_splits = max_render_width / width_per_split; |
| 457 | D_ASSERT(max_split_count > 1); |
| 458 | if (max_splits <= 1) { |
| 459 | // too wide - cannot split |
| 460 | continue; |
| 461 | } |
| 462 | idx_t split_count = duckdb::MinValue<idx_t>(max_split_count, max_splits); |
| 463 | |
| 464 | vector<ColumnRenderRow> new_renders; |
| 465 | new_renders.resize(split_count); |
| 466 | idx_t split_idx = 0; |
| 467 | for (auto &col : table.column_renders[0].columns) { |
| 468 | new_renders[split_idx % split_count].columns.push_back(std::move(col)); |
| 469 | split_idx++; |
| 470 | } |
| 471 | table.column_renders = std::move(new_renders); |
| 472 | table.render_width = duckdb::MaxValue<idx_t>(table.render_width, split_count * width_per_split); |
| 473 | } |
| 474 | |
| 475 | // group tables by db + schema |
| 476 | duckdb::map<string, duckdb::map<string, vector<ShellTableRenderInfo>>> grouped_tables; |
| 477 | for (auto &entry : table_list) { |
| 478 | grouped_tables[entry.table.database_name][entry.table.schema_name].push_back(std::move(entry)); |
| 479 | } |
| 480 | |
| 481 | vector<TableMetadataDisplayInfo> metadata_displays; |
| 482 | // for each set of table groups - make a list of displays |
| 483 | for (auto &db_entry : grouped_tables) { |
| 484 | for (auto &schema_entry : db_entry.second) { |
| 485 | auto &result = schema_entry.second; |
| 486 | // sort from biggest to smallest table |
| 487 | std::sort(result.begin(), result.end(), [](const ShellTableRenderInfo &a, const ShellTableRenderInfo &b) { |
| 488 | return a.LineCount() > b.LineCount(); |
| 489 | }); |
| 490 |
no test coverage detected