goel-skd commented on code in PR #760:
URL: https://github.com/apache/iceberg-cpp/pull/760#discussion_r3464471911


##########
src/iceberg/util/string_util.h:
##########
@@ -41,22 +40,24 @@ concept FromChars = requires(const char* p, T& v) { 
std::from_chars(p, p, v); };
 
 class ICEBERG_EXPORT StringUtils {
  public:
-  // NOTE: These convert ASCII letters only; all other bytes, including 
non-ASCII
-  // (multibyte UTF-8) bytes, are passed through unchanged.
-  // See https://github.com/apache/iceberg-cpp/issues/613.
-  static std::string ToLower(std::string_view str) {
-    return str | std::ranges::views::transform(ToLowerAscii) |
-           std::ranges::to<std::string>();
-  }
-
+  /// \brief Lower-case a UTF-8 string using Unicode simple case mapping.
+  ///
+  /// Mirrors Iceberg Java's case-insensitive handling, which lower-cases 
names with
+  /// toLowerCase(Locale.ROOT). Invalid UTF-8 input is returned unchanged.
+  /// See https://github.com/apache/iceberg-cpp/issues/613.
+  static std::string ToLower(std::string_view str);
+
+  /// \brief Upper-case ASCII letters; non-ASCII (multibyte UTF-8) bytes pass 
through
+  /// unchanged.
+  ///
+  /// Unlike ToLower this is ASCII-only, since upper-casing is not used for 
name matching.
   static std::string ToUpper(std::string_view str) {
     return str | std::ranges::views::transform(ToUpperAscii) |
            std::ranges::to<std::string>();
   }
 
   static bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs) {
-    return std::ranges::equal(
-        lhs, rhs, [](char lc, char rc) { return ToLowerAscii(lc) == 
ToLowerAscii(rc); });
+    return ToLower(lhs) == ToLower(rhs);

Review Comment:
   Checked the callers, they're all short ASCII on cold paths (metrics mode, 
`"true"`, a couple UUIDs, a header name), nothing per row. Short strings stay 
in SSO so `ToLower` doesn't allocate, and the UUID compare runs once per 
commit, so I believe there isn't a measurable regression here.
   
   Iceberg Java does the same thing: case-insensitive lookup just lowercases 
the query and hits a map
     
([`Schema.caseInsensitiveFindField`](https://github.com/apache/iceberg/blob/main/api/src/main/java/org/apache/iceberg/Schema.java#L405-L407)),
 and that map is built by lowercasing every field name once 
([`TypeUtil.indexByLowerCaseName`](https://github.com/apache/iceberg/blob/main/api/src/main/java/org/apache/iceberg/types/TypeUtil.java#L209-L228)).
 No streaming `equalsIgnoreCase` anywhere; the speed comes from caching the 
lowercased keys, which we already do in `schema.cc`/`type.cc`. So the hot path 
is covered and `EqualsIgnoreCase` is just the cold fallback.
   
   Streaming is also trickier than it looks since you can't early-out on 
length: simple lowercasing can change byte length (`İ` → `i` goes 2 bytes to 
1). 
   
   I suggest we keep this as is and revisit if a hot-path caller comes up.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to