From d063ea3ffeb2a6bd99f3a89dc7b107f9661f0b98 Mon Sep 17 00:00:00 2001 From: Priec Date: Sat, 8 Aug 2026 22:24:07 +0200 Subject: [PATCH] truncation fix and other drifts2 --- common/src/system_column.rs | 46 +++++++++++++++++++++++++++++++++++-- server | 2 +- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/common/src/system_column.rs b/common/src/system_column.rs index 23171634..15af5548 100644 --- a/common/src/system_column.rs +++ b/common/src/system_column.rs @@ -45,6 +45,34 @@ pub const TRAILING_SYSTEM_COLUMNS: [SystemColumn; 1] = [SystemColumn { pub const ACCOUNT_REFERENCE_COLUMN: &str = "account_id"; pub const ACCOUNT_API_COLUMN: &str = "account"; +/// The longest name any system column carries physically. +/// +/// Anything that names a database object after a column has to reserve room +/// for the widest name it could be given, and a user column's ordinal is far +/// shorter than these. The bound is computed from the declarations above +/// rather than picked by hand, so adding a system column moves it. +/// +/// [`ACCOUNT_API_COLUMN`] is deliberately absent: it is an API spelling, never +/// a physical column, so nothing is ever named after it. +pub const LONGEST_SYSTEM_COLUMN_NAME: usize = longest_system_column_name(); + +const fn longest_system_column_name() -> usize { + const fn longest_of(columns: &[SystemColumn], mut longest: usize) -> usize { + let mut index = 0; + while index < columns.len() { + let length = columns[index].name.len(); + if length > longest { + longest = length; + } + index += 1; + } + longest + } + + let longest = longest_of(&LEADING_SYSTEM_COLUMNS, ACCOUNT_REFERENCE_COLUMN.len()); + longest_of(&TRAILING_SYSTEM_COLUMNS, longest) +} + /// Every system column name, whether or not the column is on a given table. /// /// A name is reserved for all tables even when only some tables carry the @@ -75,8 +103,8 @@ pub fn system_column_name_list() -> String { #[cfg(test)] mod tests { use super::{ - ACCOUNT_API_COLUMN, ACCOUNT_REFERENCE_COLUMN, is_system_column, system_column_name_list, - system_column_names, + ACCOUNT_API_COLUMN, ACCOUNT_REFERENCE_COLUMN, LONGEST_SYSTEM_COLUMN_NAME, is_system_column, + system_column_name_list, system_column_names, }; #[test] @@ -98,6 +126,20 @@ mod tests { assert!(!is_system_column("column_1")); } + /// The const derivation walks the arrays directly, so this walks the + /// public iterator instead. A system column declared somewhere the const + /// function does not reach shows up here as a disagreement rather than as + /// a truncated index name much later. + #[test] + fn the_longest_name_bound_covers_every_system_column() { + let longest = system_column_names() + .map(str::len) + .max() + .expect("there is always at least one system column"); + + assert_eq!(longest, LONGEST_SYSTEM_COLUMN_NAME); + } + #[test] fn the_name_list_reads_as_a_sentence_fragment() { assert_eq!( diff --git a/server b/server index 2e4342db..e8c579bf 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 2e4342dbf48b9f9e327bb02e98aa7627ad6c7d0a +Subproject commit e8c579bf55b20fec338507542c2bc7466ddfec9a