You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by ga...@apache.org on 2026/08/21 08:33:31 UTC

(iceberg-cpp) branch main updated: fix: parse boolean properties case-insensitively (#847)

This is an automated email from the ASF dual-hosted git repository.

wgtmac pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-cpp.git


The following commit(s) were added to refs/heads/main by this push:
     new 3d68aa70 fix: parse boolean properties case-insensitively (#847)
3d68aa70 is described below

commit 3d68aa70aeacd60c6e5d30cdb44ba26221c11c2d
Author: Minh Vu <vu...@gmail.com>
AuthorDate: Fri Aug 21 10:33:26 2026 +0200

    fix: parse boolean properties case-insensitively (#847)
---
 src/iceberg/arrow/s3/arrow_s3_file_io.cc  |  4 ++--
 src/iceberg/test/arrow_s3_file_io_test.cc |  8 ++++----
 src/iceberg/test/config_test.cc           | 14 ++++++++++++++
 src/iceberg/util/config.h                 |  2 +-
 4 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/iceberg/arrow/s3/arrow_s3_file_io.cc b/src/iceberg/arrow/s3/arrow_s3_file_io.cc
index 11ef483a..7c2799f7 100644
--- a/src/iceberg/arrow/s3/arrow_s3_file_io.cc
+++ b/src/iceberg/arrow/s3/arrow_s3_file_io.cc
@@ -59,10 +59,10 @@ Result<std::optional<bool>> ParseOptionalBool(
   if (value == nullptr) {
     return std::nullopt;
   }
-  if (*value == "true") {
+  if (StringUtils::EqualsIgnoreCase(*value, "true")) {
     return true;
   }
-  if (*value == "false") {
+  if (StringUtils::EqualsIgnoreCase(*value, "false")) {
     return false;
   }
   return InvalidArgument(R"("{}" must be "true" or "false")", key);
diff --git a/src/iceberg/test/arrow_s3_file_io_test.cc b/src/iceberg/test/arrow_s3_file_io_test.cc
index 03b4b485..40719827 100644
--- a/src/iceberg/test/arrow_s3_file_io_test.cc
+++ b/src/iceberg/test/arrow_s3_file_io_test.cc
@@ -325,25 +325,25 @@ TEST_F(ArrowS3FileIOTest, EndpointScheme) {
 TEST_F(ArrowS3FileIOTest, SslEnabled) {
   auto https =
       ConfigureS3Options({{std::string(S3Properties::kEndpoint), "http://localhost:9000"},
-                          {std::string(S3Properties::kSslEnabled), "true"}});
+                          {std::string(S3Properties::kSslEnabled), "TRUE"}});
   ASSERT_THAT(https, IsOk());
   EXPECT_EQ(https->scheme, "https");
 
   auto http = ConfigureS3Options(
       {{std::string(S3Properties::kEndpoint), "https://localhost:9000"},
-       {std::string(S3Properties::kSslEnabled), "false"}});
+       {std::string(S3Properties::kSslEnabled), "FaLsE"}});
   ASSERT_THAT(http, IsOk());
   EXPECT_EQ(http->scheme, "http");
 }
 
 TEST_F(ArrowS3FileIOTest, PathStyleAccess) {
   auto virtual_addressing =
-      ConfigureS3Options({{std::string(S3Properties::kPathStyleAccess), "false"}});
+      ConfigureS3Options({{std::string(S3Properties::kPathStyleAccess), "FALSE"}});
   ASSERT_THAT(virtual_addressing, IsOk());
   EXPECT_TRUE(virtual_addressing->force_virtual_addressing);
 
   auto path_style =
-      ConfigureS3Options({{std::string(S3Properties::kPathStyleAccess), "true"}});
+      ConfigureS3Options({{std::string(S3Properties::kPathStyleAccess), "TrUe"}});
   ASSERT_THAT(path_style, IsOk());
   EXPECT_FALSE(path_style->force_virtual_addressing);
 }
diff --git a/src/iceberg/test/config_test.cc b/src/iceberg/test/config_test.cc
index 36aa9f30..0bb098ba 100644
--- a/src/iceberg/test/config_test.cc
+++ b/src/iceberg/test/config_test.cc
@@ -126,4 +126,18 @@ TEST(ConfigTest, BasicOperations) {
   ASSERT_EQ(config.Get(TestConfig::kDoubleConfig), 3.14);
 }
 
+TEST(ConfigTest, ParseBooleanIgnoringCase) {
+  auto config = TestConfig::default_properties();
+
+  for (const auto& value : {"true", "TRUE", "TrUe"}) {
+    config.mutable_configs()[TestConfig::kBoolConfig.key()] = value;
+    EXPECT_TRUE(config.Get(TestConfig::kBoolConfig));
+  }
+
+  for (const auto& value : {"false", "FALSE", "not-a-boolean"}) {
+    config.mutable_configs()[TestConfig::kBoolConfig.key()] = value;
+    EXPECT_FALSE(config.Get(TestConfig::kBoolConfig));
+  }
+}
+
 }  // namespace iceberg
diff --git a/src/iceberg/util/config.h b/src/iceberg/util/config.h
index ed847eb6..36e92237 100644
--- a/src/iceberg/util/config.h
+++ b/src/iceberg/util/config.h
@@ -54,7 +54,7 @@ U DefaultFromString(const std::string& val) {
   if constexpr (std::is_same_v<U, std::string>) {
     return val;
   } else if constexpr (std::is_same_v<U, bool>) {
-    return val == "true";
+    return StringUtils::EqualsIgnoreCase(val, "true");
   } else if constexpr ((std::is_signed_v<U> && std::is_integral_v<U>) ||
                        std::is_floating_point_v<U>) {
     ICEBERG_ASSIGN_OR_THROW(auto res, StringUtils::ParseNumber<U>(val));