Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/duckdb/extension/parquet/parquet_multi_file_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ static void BindSchema(ClientContext &context, vector<LogicalType> &return_types
#endif

res.default_expression = make_uniq<ConstantExpression>(column.default_value);
reader_bind.schema.emplace_back(std::move(res));
reader_bind.schema.emplace_back(res);
}
ParseFileRowNumberOption(reader_bind, options, return_types, names);
if (options.file_row_number) {
MultiFileColumnDefinition res("file_row_number", LogicalType::BIGINT);
res.identifier = Value::INTEGER(MultiFileReader::ORDINAL_FIELD_ID);
schema_col_names.push_back(res.name);
schema_col_types.push_back(res.type);
reader_bind.schema.emplace_back(std::move(res));
reader_bind.schema.emplace_back(res);
}

if (match_by_field_id) {
Expand Down
111 changes: 81 additions & 30 deletions src/duckdb/src/common/box_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,19 +902,11 @@ void BoxRenderer::RenderValues(const list<ColumnDataCollection> &collections, co
}
}

void BoxRenderer::RenderRowCount(string row_count_str, string shown_str, const string &column_count_str,
const vector<idx_t> &boundaries, bool has_hidden_rows, bool has_hidden_columns,
idx_t total_length, idx_t row_count, idx_t column_count, idx_t minimum_row_length,
BaseResultRenderer &ss) {
// check if we can merge the row_count_str and the shown_str
bool display_shown_separately = has_hidden_rows;
if (has_hidden_rows && total_length >= row_count_str.size() + shown_str.size() + 5) {
// we can!
row_count_str += " " + shown_str;
shown_str = string();
display_shown_separately = false;
minimum_row_length = row_count_str.size() + 4;
}
void BoxRenderer::RenderRowCount(string &row_count_str, string &readable_rows_str, string &shown_str,
const string &column_count_str, const vector<idx_t> &boundaries, bool has_hidden_rows,
bool has_hidden_columns, idx_t total_length, idx_t row_count, idx_t column_count,
idx_t minimum_row_length, BaseResultRenderer &ss) {
// check if we can merge the row_count_str, readable_rows_str and the shown_str
auto minimum_length = row_count_str.size() + column_count_str.size() + 6;
bool render_rows_and_columns = total_length >= minimum_length &&
((has_hidden_columns && row_count > 0) || (row_count >= 10 && column_count > 1));
Expand All @@ -941,23 +933,75 @@ void BoxRenderer::RenderRowCount(string row_count_str, string shown_str, const s
if (!render_anything) {
return;
}
idx_t padding = total_length - row_count_str.size() - 4;
if (render_rows_and_columns) {
padding -= column_count_str.size();
}
string extra_render_str;
// do we have to space to render the minimum_row_length and the shown string on the same row?
idx_t shown_size = readable_rows_str.size() + shown_str.size() + (readable_rows_str.empty() ? 3 : 5);
if (has_hidden_rows && padding >= shown_size) {
// we have space - render it here
extra_render_str = " (";
if (!readable_rows_str.empty()) {
extra_render_str += readable_rows_str + ", ";
}
extra_render_str += shown_str;
extra_render_str += ")";
D_ASSERT(extra_render_str.size() == shown_size);
padding -= shown_size;
readable_rows_str = string();
shown_str = string();
}

ss << config.VERTICAL;
ss << " ";
if (render_rows_and_columns) {
ss << config.VERTICAL;
ss << " ";
ss.Render(ResultRenderType::FOOTER, row_count_str);
ss << string(total_length - row_count_str.size() - column_count_str.size() - 4, ' ');
if (!extra_render_str.empty()) {
ss.Render(ResultRenderType::NULL_VALUE, extra_render_str);
}
ss << string(padding, ' ');
ss.Render(ResultRenderType::FOOTER, column_count_str);
ss << " ";
ss << config.VERTICAL;
ss << '\n';
} else if (render_rows) {
RenderValue(ss, row_count_str, total_length - 4, ResultRenderType::FOOTER);
ss << config.VERTICAL;
ss << '\n';

if (display_shown_separately) {
RenderValue(ss, shown_str, total_length - 4, ResultRenderType::FOOTER);
idx_t lpadding = padding / 2;
idx_t rpadding = padding - lpadding;
ss << string(lpadding, ' ');
ss.Render(ResultRenderType::FOOTER, row_count_str);
if (!extra_render_str.empty()) {
ss.Render(ResultRenderType::NULL_VALUE, extra_render_str);
}
ss << string(rpadding, ' ');
}
ss << " ";
ss << config.VERTICAL;
ss << '\n';
if (!readable_rows_str.empty() || !shown_str.empty()) {
// we still need to render the readable rows/shown strings
// check if we can merge the two onto one row
idx_t combined_shown_length = readable_rows_str.size() + shown_str.size() + 4;
if (combined_shown_length <= total_length) {
// we can! merge them
ss << config.VERTICAL;
ss << " ";
ss.Render(ResultRenderType::NULL_VALUE, readable_rows_str);
ss << string(total_length - combined_shown_length, ' ');
ss.Render(ResultRenderType::NULL_VALUE, shown_str);
ss << " ";
ss << config.VERTICAL;
ss << '\n';
readable_rows_str = string();
shown_str = string();
}
ValueRenderAlignment alignment =
render_rows_and_columns ? ValueRenderAlignment::LEFT : ValueRenderAlignment::MIDDLE;
if (!readable_rows_str.empty()) {
RenderValue(ss, "(" + readable_rows_str + ")", total_length - 4, ResultRenderType::NULL_VALUE, alignment);
ss << config.VERTICAL;
ss << '\n';
}
if (!shown_str.empty()) {
RenderValue(ss, "(" + shown_str + ")", total_length - 4, ResultRenderType::NULL_VALUE, alignment);
ss << config.VERTICAL;
ss << '\n';
}
Expand Down Expand Up @@ -1011,16 +1055,23 @@ void BoxRenderer::Render(ClientContext &context, const vector<string> &names, co
if (has_limited_rows) {
row_count_str = "? rows";
}
string readable_rows_str;
if (config.large_number_rendering == LargeNumberRendering::FOOTER && !has_limited_rows) {
readable_rows_str = TryFormatLargeNumber(to_string(row_count));
if (!readable_rows_str.empty()) {
readable_rows_str += " rows";
}
}
string shown_str;
bool has_hidden_rows = top_rows < row_count;
if (has_hidden_rows) {
shown_str = "(";
if (has_limited_rows) {
shown_str += ">" + FormatNumber(to_string(config.limit - 1)) + " rows, ";
}
shown_str += FormatNumber(to_string(top_rows + bottom_rows)) + " shown)";
shown_str += FormatNumber(to_string(top_rows + bottom_rows)) + " shown";
}
auto minimum_row_length = MaxValue<idx_t>(row_count_str.size(), shown_str.size()) + 4;
auto minimum_row_length =
MaxValue<idx_t>(MaxValue<idx_t>(row_count_str.size(), shown_str.size() + 2), readable_rows_str.size() + 2) + 4;

// fetch the top and bottom render collections from the result
auto collections = FetchRenderCollections(context, result, top_rows, bottom_rows);
Expand Down Expand Up @@ -1073,7 +1124,7 @@ void BoxRenderer::Render(ClientContext &context, const vector<string> &names, co
if (config.render_mode == RenderMode::COLUMNS) {
if (has_hidden_columns) {
has_hidden_rows = true;
shown_str = " (" + to_string(column_count - 3) + " shown)";
shown_str = to_string(column_count - 3) + " shown";
} else {
shown_str = string();
}
Expand All @@ -1084,7 +1135,7 @@ void BoxRenderer::Render(ClientContext &context, const vector<string> &names, co
}
}

RenderRowCount(std::move(row_count_str), std::move(shown_str), column_count_str, boundaries, has_hidden_rows,
RenderRowCount(row_count_str, readable_rows_str, shown_str, column_count_str, boundaries, has_hidden_rows,
has_hidden_columns, total_length, row_count, column_count, minimum_row_length, ss);
}

Expand Down
4 changes: 2 additions & 2 deletions src/duckdb/src/common/progress_bar/progress_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ void ProgressBar::Update(bool final) {
if (final) {
FinishProgressBarPrint();
} else {
PrintProgress(LossyNumericCast<int>(query_progress.percentage.load()));
PrintProgress(query_progress.percentage.load());
}
}
}

void ProgressBar::PrintProgress(int current_percentage_p) {
void ProgressBar::PrintProgress(double current_percentage_p) {
D_ASSERT(display);
display->Update(current_percentage_p);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,65 @@ int32_t TerminalProgressBarDisplay::NormalizePercentage(double percentage) {
return int32_t(percentage);
}

void TerminalProgressBarDisplay::PrintProgressInternal(int32_t percentage) {
static string FormatETA(double seconds, bool elapsed = false) {
// for terminal rendering purposes, we need to make sure the length is always the same
// we pad the end with spaces if that is not the case
// the maximum length here is "(~10.35 minutes remaining)" (26 bytes)
// always pad to this amount
static constexpr idx_t RENDER_SIZE = 26;
// Desired formats:
// 00:00:00.00 remaining
// unknown remaining
// 00:00:00.00 elapsed
if (!elapsed && seconds > 3600 * 99) {
// estimate larger than 99 hours remaining
string result = "(>99 hours remaining)";
result += string(RENDER_SIZE - result.size(), ' ');
return result;
}
if (seconds < 0) {
// Invalid or unknown ETA, skip rendering estimate
return string(RENDER_SIZE, ' ');
}

// Round to nearest centisecond as integer
auto total_centiseconds = static_cast<uint64_t>(std::llround(seconds * 100.0));

// Split into seconds and centiseconds
uint64_t total_seconds = total_centiseconds / 100;
uint32_t centiseconds = static_cast<uint32_t>(total_centiseconds % 100);

// Break down total_seconds
uint64_t hours = total_seconds / 3600;
uint32_t minutes = static_cast<uint32_t>((total_seconds % 3600) / 60);
uint32_t secs = static_cast<uint32_t>(total_seconds % 60);
string result;
result = "(";
if (!elapsed) {
if (hours == 0 && minutes == 0 && secs == 0) {
result += StringUtil::Format("<1 second");
} else if (hours == 0 && minutes == 0) {
result += StringUtil::Format("~%u second%s", secs, secs > 1 ? "s" : "");
} else if (hours == 0) {
auto minute_fraction = static_cast<uint32_t>(static_cast<double>(secs) / 60.0 * 10);
result += StringUtil::Format("~%u.%u minutes", minutes, minute_fraction);
} else {
auto hour_fraction = static_cast<uint32_t>(static_cast<double>(minutes) / 60.0 * 10);
result += StringUtil::Format("~%llu.%u hours", hours, hour_fraction);
}
result += " remaining";
} else {
result += StringUtil::Format("%02llu:%02u:%02u.%02llu", hours, minutes, secs, centiseconds);
result += " elapsed";
}
result += ")";
if (result.size() < RENDER_SIZE) {
result += string(RENDER_SIZE - result.size(), ' ');
}
return result;
}

void TerminalProgressBarDisplay::PrintProgressInternal(int32_t percentage, double seconds, bool finished) {
string result;
// we divide the number of blocks by the percentage
// 0% = 0
Expand Down Expand Up @@ -52,22 +110,26 @@ void TerminalProgressBarDisplay::PrintProgressInternal(int32_t percentage) {
}
result += PROGRESS_END;
result += " ";
result += FormatETA(seconds, finished);

Printer::RawPrint(OutputStream::STREAM_STDOUT, result);
}

void TerminalProgressBarDisplay::Update(double percentage) {
const double current_time = GetElapsedDuration();

// Filters go from 0 to 1, percentage is from 0-100
const double filter_percentage = percentage / 100.0;
ukf.Update(filter_percentage, current_time);

double estimated_seconds_remaining = ukf.GetEstimatedRemainingSeconds();
auto percentage_int = NormalizePercentage(percentage);
if (percentage_int == rendered_percentage) {
return;
}
PrintProgressInternal(percentage_int);
PrintProgressInternal(percentage_int, estimated_seconds_remaining);
Printer::Flush(OutputStream::STREAM_STDOUT);
rendered_percentage = percentage_int;
}

void TerminalProgressBarDisplay::Finish() {
PrintProgressInternal(100);
PrintProgressInternal(100, GetElapsedDuration(), true);
Printer::RawPrint(OutputStream::STREAM_STDOUT, "\n");
Printer::Flush(OutputStream::STREAM_STDOUT);
}
Expand Down
Loading
Loading