Implement ascii_downcase and ascii_upcase in C (#3689)

Both were defined as explode | map(...) | implode, which took 4 seconds
on a 10 MB string, about 90 times as long as parsing it.

Change the case of A-Z or a-z a byte at a time in C, copying multibyte
UTF-8 sequences unchanged, so the output stays the same and the 10 MB
case now takes about 60 ms including parsing. On a non-string input the
error now names the function, "ascii_downcase input must be a string",
instead of "explode input must be a string".
This commit is contained in:
Michiel van Slobbe authored and GitHub committed 2026-10-25 14:18:21 +09:00
1 parent bd56a74562
commit 864d769d88
3 files changed
+50 -6

No files matched your search

+18
View File
@@ -1888,6 +1888,24 @@ ascii_upcase
"useful but not for é"
"USEFUL BUT NOT FOR é"
# Only A-Z and a-z change; the neighbouring bytes @ [ ` { and non-ASCII do not
[ascii_downcase, ascii_upcase]
"@AZ[`az{ ÀÉé Dž 日本 😀 0123456789 THE QUICK brown fox JUMPS over"
["@az[`az{ ÀÉé Dž 日本 😀 0123456789 the quick brown fox jumps over","@AZ[`AZ{ ÀÉé Dž 日本 😀 0123456789 THE QUICK BROWN FOX JUMPS OVER"]
[ascii_downcase, ascii_upcase]
""
["",""]
# An embedded NUL does not end the string
[ascii_downcase, ascii_upcase]
"A\u0000z"
["a\u0000z","A\u0000Z"]
[.[] | try ascii_downcase catch ., try ascii_upcase catch .]
[null, ["A"]]
["ascii_downcase input must be a string","ascii_upcase input must be a string","ascii_downcase input must be a string","ascii_upcase input must be a string"]
bsearch(0,1,2,3,4)
[1,2,3]
-1