On 2014-08-19 04:17, Gavin Lambert wrote:
On 19/08/2014 09:55, Roland Bock wrote:
I'm guessing that the problem exists because select is lazily executed. C++ objects corresponding to the data aren't created (e.g. std::string, int, float, etc.). Instead some pointers to buffers are kept (in sqlpp::result_field_t?). And C++ objects are created and returned later from value() method or conversion operators each time one of them is called. Is that right? Not quite. Lets look at integral.h and the partial specialization of
template
result_field_t {...}; Now, this contains an int64_t value. The address of this value is given to the backend in the method bind() when fetching each result row (no laziness here). It seems to me that I cannot replace int64_t by boost::optional
. For instance, I cannot call get() to obtain the address of the value if the optional is not initialized (I would run into an assert). Presumably it is the backend that knows whether the column/result is NULL or not. Correct. Therefore it should be the backend's responsibility to fill in the optional correctly If I had an optional in the result field, yes. -- ie. you should be passing an address/reference to the entire optional, not the internal integer. Some backends have functions like this (simplified):
void get_int_field(int index, int* retval); How would I interact with such an interface if I had an optional<int>? As suggested by Adam: optional<int> member; ... if (!member) member = 0 get_int_field(17, member.get());
Otherwise how does the backend return a NULL value?
The backend is called with two parameters, one pointer for the value, the other for the is_null information. Regards, Roland