diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index 3f3fb3c15..b4ce9e425 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -8012,8 +8012,12 @@ impl Value { pub fn exec_length(&self) -> Self { match self { Value::Text(t) => { - // Count Unicode scalar values (characters) - Value::Integer(t.as_str().chars().count() as i64) + let s = t.as_str(); + let len_before_null = s.find('\0').map_or_else( + || s.chars().count(), + |null_pos| s[..null_pos].chars().count(), + ); + Value::Integer(len_before_null as i64) } Value::Integer(_) | Value::Float(_) => { // For numbers, SQLite returns the length of the string representation diff --git a/testing/scalar-functions.test b/testing/scalar-functions.test index 9ef2f74b3..46133cd14 100755 --- a/testing/scalar-functions.test +++ b/testing/scalar-functions.test @@ -939,6 +939,11 @@ do_execsql_test parse-large-integral-numeric-string-as-number { SELECT (-104614899632619 || 45597) > CAST(0 AS NUMERIC); } {0} +# https://github.com/tursodatabase/turso/issues/3317 +do_execsql_test length-999123 { + select length('a' || char(0) || 'b'); +} {1} + # TODO: sqlite seems not enable soundex() by default unless build it with SQLITE_SOUNDEX enabled. # do_execsql_test soundex-text { # select soundex('Pfister'), soundex('husobee'), soundex('Tymczak'), soundex('Ashcraft'), soundex('Robert'), soundex('Rupert'), soundex('Rubin'), soundex('Kant'), soundex('Knuth'), soundex('x'), soundex('');