fix(sql-dialect): enforce Postgres/Oracle identifier ceilings in UTF-8 bytes (Driver.Sql.Dialect-001)

NAMEDATALEN-1 (63) and Oracle 12.2's 128 are byte limits in the database
encoding, not character counts, so a 32-character Cyrillic name passed
ident.Length and was then silently truncated (Postgres) or rejected by the
server (Oracle). Both dialects now measure Encoding.UTF8.GetByteCount and say
'bytes' in the rejection. SqlServerDialect deliberately keeps ident.Length —
sysname is nvarchar(128), a real character limit — pinned by a control test.
This commit is contained in:
Joseph Doherty
2026-08-10 07:58:04 -04:00
parent 94b8633e68
commit 74594e6083
6 changed files with 102 additions and 8 deletions
@@ -18,6 +18,10 @@ public sealed class SqlServerDialect : ISqlDialect
/// T-SQL's regular-identifier ceiling (<c>sysname</c> = <c>nvarchar(128)</c>). Enforced because a
/// longer string cannot name a real catalog object — it is either a config mistake or padding, and
/// rejecting it keeps the quoted output bounded.
/// <para><b>The unit here is genuinely CHARACTERS</b> (UTF-16 code units, which is what
/// <c>nvarchar(128)</c> counts), deliberately unlike <c>PostgresDialect</c> and <c>OracleDialect</c>,
/// whose ceilings are byte limits in the database encoding. Measuring bytes here would reject a legal
/// 128-character non-ASCII name.</para>
/// </summary>
internal const int MaxIdentifierLength = 128;