in sql_utils/public/error_helpers.cc [182:245]
static void GetTruncatedInputStringInfo(absl::string_view input,
const ErrorLocation& location,
int max_width_in,
std::string* truncated_input,
int* error_column) {
// We don't allow a max_width below a certain size.
constexpr int kMinimumMaxWidth = 30;
// If the error line is longer than max_width, give a substring of up
// to max_width characters, with the caret near the middle of it.
// We need some minimum width.
const int max_width = std::max(max_width_in, kMinimumMaxWidth);
SQL_DCHECK_GT(location.line(), 0);
SQL_DCHECK_GT(location.column(), 0);
ParseLocationTranslator translator(input);
absl::StatusOr<absl::string_view> line_text =
translator.GetLineText(location.line());
SQL_DCHECK_OK(line_text.status());
*truncated_input = translator.ExpandTabs(line_text.value_or(""));
// location.column() may be one off the end of the line for EOF errors.
SQL_DCHECK_LE(location.column(), truncated_input->size() + 1);
// error_column is 0-based.
*error_column =
std::max(1, std::min(static_cast<int>(truncated_input->size() + 1),
location.column())) -
1;
if (truncated_input->size() > max_width) {
const int one_half = max_width / 2;
const int one_third = max_width / 3;
// If the error is near the start, just use a prefix of the string.
if (*error_column > max_width - one_third) {
// Otherwise, try to find a word boundary to start the string on
// that puts the caret in the middle third of the output line.
int found_start = -1;
for (int start_column = std::max(0, *error_column - 2 * one_third);
start_column < std::max(0, *error_column - one_third);
++start_column) {
if (IsWordStart(*truncated_input, start_column)) {
found_start = start_column;
break;
}
}
if (found_start == -1) {
// Didn't find a good separator. Just split in the middle.
found_start = std::max(*error_column - one_half, 0);
}
// Add ... prefix if necessary.
if (found_start < 3) {
found_start = 0;
} else {
*truncated_input =
absl::StrCat("...", truncated_input->substr(found_start));
*error_column -= found_start - 3;
}
}
*truncated_input = PrettyTruncateUTF8(*truncated_input, max_width);
SQL_DCHECK_LE(*error_column, truncated_input->size());
}
}