Theoretically, '0' will get type cast to the column type, but if the type cannot be inferred from the table information, then you get '0' back, which seems odd to me.
Surely it should be 0 rather than '0' passed to type_cast_using_column, no?
Tekin Suleyman
On Saturday, 14 January 2012 at 8:37 AM, Ken Collins wrote:
I remember a long time ago I had a patch for average that would trust what the DB returned, in my case integers.It would be nice if calculations could always rely on the raw_connection to return data types converted to ruby primitives correctly. Not sure if that '0' should be a 0 or not, maybe be helpful to see what fails if changed?- Ken
Yea, our Ruby ODBC does not return proper types, but our TinyTDS which has been out for a year or more now does. Just like MySQL2 which it was modeled after.
> In preparation for 4.0 perhaps we could do an audit of the various database drivers and make sure they return the correct types. After that we could remove the custom typecasting we do?
I would be for that!
- Ken
It depends on the level of API people want to use. For example, PG
always returns strings. That means we need to know the types for which
we're querying. Say someone does this against pg:
connection.execute 'select 1.2 + 20'
we can't know to cast that to a float. Even doing regexp tests will be
wrong since someone may have tried to select a string.
We can do automatic casting, but it's going to break down at some point
depending on the level of abstraction and the database used.
--
Aaron Patterson
http://tenderlovemaking.com/
Actually, you can if you use the mysql, pg, postgres, and postgres-pr
drivers (and most other drivers that return strings for everything).
When you get the results of the query, you can query the metadata of
the results to get the types of the columns. Sequel uses this
information to typecast such results correctly, and there is no reason
ActiveRecord couldn't do the same:
irb(main):001:0> DB['SELECT 1'].single_value
=> 1
irb(main):002:0> DB["SELECT '1'"].single_value
=> "1"
irb(main):003:0> DB["SELECT 1.2"].single_value
=> #<BigDecimal:20e8334b0,'0.12E1',18(18)>
irb(main):004:0> DB["SELECT 1.2::real"].single_value
=> 1.2
Jeremy
It depends on the level of API people want to use. For example, PGalways returns strings. That means we need to know the types for whichwe're querying. Say someone does this against pg:connection.execute 'select 1.2 + 20'we can't know to cast that to a float. Even doing regexp tests will bewrong since someone may have tried to select a string.
We can do automatic casting, but it's going to break down at some pointdepending on the level of abstraction and the database used.
I'm not sure if the pg "over the wire" protocol contains that
information, but I can tell you that libpg doesn't provide functions for
casting to C types (that I can find).
See PQgetvalue:
http://www.postgresql.org/docs/6.4/static/libpq-chapter16943.htm
PQftype returns a type id integer that represents the database type.
The ruby postgres drivers (pg, postgres, postgres-pr) expose this
information via the type or ftype method on the PGresult class. The
common database types have fixed type id integers you can statically
map to ruby classes (16 -> boolean, 700 and 701 -> float, etc.).
You may be correct that libpq lacks a function that casts to C types.
But it's fairly simple to cast the C string directly to the desired
ruby type using a mapping based on the type id integer.
Jeremy
--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Yes, please. I will merge it. Only two suggestions:
1) Assign the OIDs to constants
2) Break out the giant case / when to a method
Thanks!