unknown
1970-01-01 00:00:00 UTC
--047d7b62432c7174ec04e21a81a1
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable <div dir="ltr"><div style><br></div><div style>Hi,</div><div style><br></div><div style>The problem as I see it is not really with a specific mapping of some unsigned types to signed types, but with the fact that v.get<...>() throws when the types don't match exactly, instead of trying to put the value of the requested field into whatever type the user wants it in (and only throwing when that's not possible.) �The general understanding was that soci should be changed, I think Mateusz (cc-ed) started writing a design doc about it.</div> <div style><br></div><div style>As long as we keep the current behavior, i.e., force the users to use specific integral types, I personally think the current mapping is very sane. �The most natural default integral type in C++ is int so it's fairly obvious that all smaller types, signed or not, should be interpreted as int. �And for unsigned long long there is no choice either because no other type is large enough to fit all values from unsigned long long. �So the only non-obvious choice was to convert unsigned long to dt_long_long, which can be justified by consistency with all smaller unsigned types which are interpreted as a signed value of a larger type. �Even if that decision were concluded wrong (which I don't think it was) it would be hard to change now since user code may depend on it (if we change the type some user code may start to throw.)</div> <div style><br></div><div style>Thanks,</div><div style><br></div><div style>Aleksander</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jul 22, 2013 at 1:38 PM, Daniel Walter <span dir="ltr"><<a href="mailto:***@helmundwalter.de" target="_blank">***@helmundwalter.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi there,<br>
<br>
I am experiencing some annoying problems with type casting in mysql backend.<br>
In my non trivial SQL query I am doing casts for generated columns to<br>
avoid problems with the type the server sends for each column.<br>
<br>
,CAST(COALESCE((p2e.inserted IS NOT NULL),0) AS UNSIGNED) AS 'exists'<br>
,CAST(COALESCE(p2e.active,0) AS UNSIGNED) AS 'active'<br>
,CAST(UNIX_TIMESTAMP(COALESCE(p2e.last_full_update,0)) AS UNSIGNED)<br>
AS 'last_full_update'<br>
,CAST(0 AS UNSIGNED) AS already_ordered<br>
<br>
The problem is, that these "CAST" columns do not getting the same type<br>
from server! For example field "exists" and "active" are of type<br>
MYSQL_TYPE_LONG (unsigned flag set) and "already_ordered" and<br>
"last_full_update" are of type MYSQL_TYPE_LONGLONG (unsigned flag set).<br>
So I cant rely on the resulting type of the "CAST" call.<br>
<br>
Here are the lines with the problem from statement.cpp in mysql backend:<br>
<br>
case FIELD_TYPE_LONG: //MYSQL_TYPE_LONG:<br>
type = field->flags & UNSIGNED_FLAG ? dt_long_long<br>
: dt_integer;<br>
break;<br>
case FIELD_TYPE_LONGLONG: //MYSQL_TYPE_LONGLONG:<br>
type = field->flags & UNSIGNED_FLAG ? dt_unsigned_long_long :<br>
dt_long_long;<br>
break;<br>
<br>
<br>
The problem shows up if i try to use such a field in my orm mapping. At<br>
the beginning I used:<br>
<br>
p.exists = v.get<long long>("exists", 0);<br>
<br>
Which is at least logically wrong. Because i casted the column to<br>
"UNSIGNED" and the mapping from the MySQL backend returned an signed<br>
type? But, not matter, this code was working right... until the type<br>
changed to MYSQL_TYPE_LONGLONG. The maped type was than "unsigned long<br>
long" and I got the "bad_cast" error.<br>
<br>
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable <div dir="ltr"><div style><br></div><div style>Hi,</div><div style><br></div><div style>The problem as I see it is not really with a specific mapping of some unsigned types to signed types, but with the fact that v.get<...>() throws when the types don't match exactly, instead of trying to put the value of the requested field into whatever type the user wants it in (and only throwing when that's not possible.) �The general understanding was that soci should be changed, I think Mateusz (cc-ed) started writing a design doc about it.</div> <div style><br></div><div style>As long as we keep the current behavior, i.e., force the users to use specific integral types, I personally think the current mapping is very sane. �The most natural default integral type in C++ is int so it's fairly obvious that all smaller types, signed or not, should be interpreted as int. �And for unsigned long long there is no choice either because no other type is large enough to fit all values from unsigned long long. �So the only non-obvious choice was to convert unsigned long to dt_long_long, which can be justified by consistency with all smaller unsigned types which are interpreted as a signed value of a larger type. �Even if that decision were concluded wrong (which I don't think it was) it would be hard to change now since user code may depend on it (if we change the type some user code may start to throw.)</div> <div style><br></div><div style>Thanks,</div><div style><br></div><div style>Aleksander</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jul 22, 2013 at 1:38 PM, Daniel Walter <span dir="ltr"><<a href="mailto:***@helmundwalter.de" target="_blank">***@helmundwalter.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi there,<br>
<br>
I am experiencing some annoying problems with type casting in mysql backend.<br>
In my non trivial SQL query I am doing casts for generated columns to<br>
avoid problems with the type the server sends for each column.<br>
<br>
,CAST(COALESCE((p2e.inserted IS NOT NULL),0) AS UNSIGNED) AS 'exists'<br>
,CAST(COALESCE(p2e.active,0) AS UNSIGNED) AS 'active'<br>
,CAST(UNIX_TIMESTAMP(COALESCE(p2e.last_full_update,0)) AS UNSIGNED)<br>
AS 'last_full_update'<br>
,CAST(0 AS UNSIGNED) AS already_ordered<br>
<br>
The problem is, that these "CAST" columns do not getting the same type<br>
from server! For example field "exists" and "active" are of type<br>
MYSQL_TYPE_LONG (unsigned flag set) and "already_ordered" and<br>
"last_full_update" are of type MYSQL_TYPE_LONGLONG (unsigned flag set).<br>
So I cant rely on the resulting type of the "CAST" call.<br>
<br>
Here are the lines with the problem from statement.cpp in mysql backend:<br>
<br>
case FIELD_TYPE_LONG: //MYSQL_TYPE_LONG:<br>
type = field->flags & UNSIGNED_FLAG ? dt_long_long<br>
: dt_integer;<br>
break;<br>
case FIELD_TYPE_LONGLONG: //MYSQL_TYPE_LONGLONG:<br>
type = field->flags & UNSIGNED_FLAG ? dt_unsigned_long_long :<br>
dt_long_long;<br>
break;<br>
<br>
<br>
The problem shows up if i try to use such a field in my orm mapping. At<br>
the beginning I used:<br>
<br>
p.exists = v.get<long long>("exists", 0);<br>
<br>
Which is at least logically wrong. Because i casted the column to<br>
"UNSIGNED" and the mapping from the MySQL backend returned an signed<br>
type? But, not matter, this code was working right... until the type<br>
changed to MYSQL_TYPE_LONGLONG. The maped type was than "unsigned long<br>
long" and I got the "bad_cast" error.<br>
<br>