SOCI / soci

Official repository of the SOCI - The C++ Database Access Library
http://soci.sourceforge.net/
Boost Software License 1.0
1.37k stars 472 forks source link

PostgreSQL: Error: Null value not allowed for this type #1014

Closed frameworker2019 closed 1 year ago

frameworker2019 commented 1 year ago

It seems even the table declaration allows a NULL value, SOCI throws always the "Null value not allowed" exception:

\d table1
               Table "public.table1"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 id     | integer |           |          | 

insert into table1 values (99);
INSERT 0 1
insert into table1 values (NULL);
INSERT 0 1

select * from table1;
 id 
----
 99

(2 rows)

This is my code:

struct Table1 {
    int id;
};

namespace soci
{
    template<>
    struct type_conversion<Table1>
    {
        typedef values base_type;

        static void from_base(values const & v, indicator , Table1 & t)
        {
            t.id = v.get<int>("id");
        }

        static void to_base(const Table1 & t, values & v, indicator & ind)
        {
            v.set("id", t.id);
            ind = i_ok;
        }
    };
}

<snip>

        statement st = (sql.prepare << "select id from table1", into(table));
        st.execute();
        long rows = st.get_affected_rows();
        while (st.fetch()) {
            tables.push_back(table);
        }

        for(Table1 t : tables) {
            printf("id = %d\n", t.id);
        }

To circumvent the situation I have to write:

  t.id = v.get<int>("id", -1);

even the table definition does not declare a NOT NULL constraint on the "id" column. Is this an understanding issue that I have?

zann1x commented 1 year ago

There is no way to meaningfully store NULL in an int variable. This means you have to provide a default value that SOCI can fall back on.

The relevant section in the documentation:

get functions that return the value of the column given by position or name. If the column contains null, then these functions either return the provided "default" nullValue or throw an exception.

vadz commented 1 year ago

This is indeed working as expected, so closing.