Skip to content

Handling of boolean values on postgres #69

@mcraveiro

Description

@mcraveiro

Hi sqlgen developers,

Once more thanks for a great library. I am trying to get my head around how the processing of bools works in postgres. I have a simple struct with a field:

struct account_entity {
...
    bool is_admin;
...
}

I can see the SQL maps to the idiomatic postgres DML:

"is_admin" BOOLEAN NOT NULL

The field is populated in postgres as expected:

[ores@localhost:5434 (00:24:46) oresdb ]$ SELECT is_admin FROM accounts;
 is_admin 
----------
 f
 f
 f
(3 rows)

However, I get an error reading the field:

2025-10-22 01:05:26.406239 [ERROR] [ores.accounts.repository.account_repository] Failed to parse field 'is_admin': stoll

I'm rather afraid I am not an expert in the C++ type system :-) but maybe the problem stems from the fact that we are processing ints before doubles in Parser_default.hpp:

  try {
        if constexpr (std::is_floating_point_v<Type>) {
          return static_cast<Type>(std::stod(*_str));
        } else if constexpr (std::is_integral_v<Type>) {
          return static_cast<Type>(std::stoll(*_str));
        } else if constexpr (std::is_same_v<Type, bool>) {
          return std::stoi(*_str) != 0;
        } else if constexpr (std::is_enum_v<Type>) {
          if (auto res = rfl::string_to_enum<Type>(*_str)) {
            return Type{*res};
          } else {
            return error(res.error());

Switching these lines around does result in using stoi instead of stoll, e.g.:

  try {
        if constexpr (std::is_floating_point_v<Type>) {
          return static_cast<Type>(std::stod(*_str));
        } else if constexpr (std::is_same_v<Type, bool>) {
          return std::stoi(*_str) != 0;
        } else if constexpr (std::is_integral_v<Type>) {
          return static_cast<Type>(std::stoll(*_str));
        } else if constexpr (std::is_enum_v<Type>) {
          if (auto res = rfl::string_to_enum<Type>(*_str)) {
            return Type{*res};
          } else {
            return error(res.error());

However, we then bump into the next problem:

#0  0x00007ffff7cb93c1 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x00007ffff7ca9a0e in std::__throw_invalid_argument(char const*) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00005555556d71c7 in __gnu_cxx::__stoa<long, int, char, int> (__convf=0x7ffff7a2c490 <__GI___isoc23_strtol>, __name=0x555555e816bb "stoi", __str=0x55555638a718 "f", __idx=0x0, __base=10) at /usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/ext/string_conversions.h:87

Basically stoa is not happy converting f into a number:

(gdb) p _str
$1 = std::optional = {[contained value] = "f"}

Now, I am probably missing something obvious in all of this so please correct me if I've gone astray. But to the untrained eye, it seems some kind of conversion is needed in order to be able to use postgres boolean to a regular c++ bool? Did I miss something in the docs, and if so apologies.

Many thanks for your time.

Marco

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions