set_field_type() (PostgreSQL only)

All tables have a set_field_type() method, which changes the types and/or the NOT NULL settings of one or more columns in the target. It's a wrapper for the following SQL constructs:

But back to our story. As we left it in the previous section, the SQL table points conformed to the table object newer_point. In particular, it had a REAL column corresponding to a member declared float height.

But now we decide that heights will require double precision. In PostgreSQL terms, that's a change from REAL to DOUBLE PRECISION. But we work in C++, so for us it's a change from float to double. So our table is going to need a new value type (again). Let's define it:

struct point_xhd {
    float x;
    double height;
QUINCE_MAP_CLASS(point_xhd, (x)(height))

and let's construct the latest table object:

table<point_xhd> newest_points(db, "points", &point_xhd::x);

Now, to make the target conform to newest_points, we change the column type:


which says:

In newest_points's target, change the type of the column that newest_points->height represents, from whatever it might be now, to the SQL type that newest_points->height uses.

The existing values in the affected column are converted from the old type to the new type, as if by a server-side cast.

Here we passed a double mapper, so one column changed type; but we can pass a mapper for any mapped type. If it is a multi-column type, then set_field_type() will set the types of all the columns, provided that columns already exist with the names that the mapper expects.

We can use set_field_type() to change optionals to non-optionals or vice versa, again with the proviso that columns already exist with the names that the mapper expects [14] . Then set_field_type() will change the NOT NULL settings, from whatever they might be now, to the settings that the mapper expects (described here).

[14] The only effect of the proviso is that we can't change a T to a boost::optional<T> when T is a type that can be represented by all NULLs. E.g. you can't change a boost::optional<float> to a boost::optional<boost::optional<float>>. It's not a restriction you're likely to run into.