Code of Conduct
AI Policy
Versions
Elixir 1.20.2
Erlang/OTP 29 (erts-17.0.3)
ash 3.33.2
ash_sql 0.7.3
ash_postgres 2.13.1
Operating system
macOS 26.5.2 (Darwin 25.5.0) arm64
Current Behavior
With config :ash, :default_string_length_count, :codepoints, a max_length constraint is enforced by two different counts:
- non-atomic: Ash core evaluates in Elixir:
codepoints_length/2, raw codepoints
- atomic:
Ash.Type.String.apply_atomic_constraints/2 builds string_length(expr, :codepoints), which ash_sql renders as length(normalize(...)), so Postgres counts NFC-normalized codepoints
These may differ depending on the string.
Reproduction
repro - included below
Expected Behavior
Regardless of the string, or whether evaluated in the database or memory, the answer should be the raw codepoint of the value as stored.
Code of Conduct
AI Policy
Versions
Elixir 1.20.2
Erlang/OTP 29 (erts-17.0.3)
ash 3.33.2
ash_sql 0.7.3
ash_postgres 2.13.1
Operating system
macOS 26.5.2 (Darwin 25.5.0) arm64
Current Behavior
With
config :ash, :default_string_length_count, :codepoints, amax_lengthconstraint is enforced by two different counts:codepoints_length/2, raw codepointsAsh.Type.String.apply_atomic_constraints/2buildsstring_length(expr, :codepoints), which ash_sql renders aslength(normalize(...)), so Postgres counts NFC-normalized codepointsThese may differ depending on the string.
Reproduction
repro - included below
Expected Behavior
Regardless of the string, or whether evaluated in the database or memory, the answer should be the raw codepoint of the value as stored.