PDO types

php.internals

Timm Friebe

21 years ago
Hi, while testing PDO I was astonished to see that all values (regardless of their types in the database) are returned as strings (in all extensions except for PgSQL). Why is that so? It _is_ quite inconsistent, isn't it? Wasn't PDO supposed to _unify_ the RDBMS access apis?
-- Timm If it ain't broken, it doesn't have enough features yet

Wez Furlong

21 years ago
This is by design. PDO is deliberately very thin on type support, prefering to give the script author more control over type conversion by using the PHP built-in type juggling features. PgSQL returns other types because it is one of 2 drivers that gives you what it's got, rather than what you ask for. I didn't originally plan for those two to work that way, it just works out to be more efficient and less painful for those drivers to do it that. PDO's goal isn't total unification, but "close-enough unification". If you want something all-encompassing, you should consider a heavier-weight abstraction layer, like MDB2. --Wez. On Sat, 19 Feb 2005 19:15:03 +0100, Timm Friebe <thekid@thekid.de> wrote:

Lukas Smith

21 years ago
Timm Friebe wrote:
> while testing PDO I was astonished to see that all values (regardless of > their types in the database) are returned as strings (in all extensions > except for PgSQL). Why is that so? It _is_ quite inconsistent, isn't it? > Wasn't PDO supposed to _unify_ the RDBMS access apis?
I dont know the actual implementation but at the last meeting we came to the conclusion that PDO will pass back proper types if the RDBMS does and strings if the RDBMS doesnt. Anything more would require the users from providing this metadata or PDO jumping through alot of hoops to fetch this information from the RDBMS. BTW: ibase will probably (eventually) also fall in the sam categorie because iirc Ard was the one who started the discussion on this at the last meeting. regards, Lukas

Timm Friebe

21 years ago
On Sun, 2005-02-20 at 10:44 +0100, Lukas Smith wrote:
> Timm Friebe wrote: > > > while testing PDO I was astonished to see that all values (regardless of > > their types in the database) are returned as strings (in all extensions > > except for PgSQL). Why is that so? It _is_ quite inconsistent, isn't it? > > Wasn't PDO supposed to _unify_ the RDBMS access apis? > > I dont know the actual implementation but at the last meeting we came to > the conclusion that PDO will pass back proper types if the RDBMS does > and strings if the RDBMS doesnt. Anything more would require the users > from providing this metadata or PDO jumping through alot of hoops to > fetch this information from the RDBMS.
For pdo_mysql (and probably most others), that's one switch statement to solve them all:) In ext/firebird, the relevant sourcecode is even #ifdef'd out. If PDO extensions would returns numbers (int, float) and booleans as their corresponding PHP datatypes this would save memory. That, for example, was the main motivation I did this in ext/sybase_ct. There, I try a best-match policy: For "integers": * If the number "fits" into a long, it will be returned into a long (PHP datatype integer). This can be done safely for tinyint and shortint, for example. * If the number does not fit, I will try to convert it into a double (PHP datatype float). This is the case for e.g. numeric(10) - values might not fit. This is the same what PHP does when adding 1 to LONG_MAX, for instance. If - in the procedure of doing so, strtod() gives an ERANGE or if the length overflows EG(precision), I will return a string. For "floats" * If the length of the returned value exceeds EG(precision) or if strtod() returns an ERANGE, I will return a string; a float otherwise. While this sound like an awful lot of code, it actually boils down to a couple of lines of C (which will be definitely faster than if users first fetch column metadata and then "cast" dependant on the information they retrieve from that). Talking about that, maybe PDO should start returning Date objects instead of stupid string representations or sequences of numbers of those (where users will start preg_match()ing or strtotime()ing around if they want to do arithmetic with the returned value)...
-- Timm If it ain't broken, it doesn't have enough features yet

Wez Furlong

21 years ago
On Sun, 20 Feb 2005 12:36:01 +0100, Timm Friebe <thekid@thekid.de> wrote:
> * If the number does not fit, I will try to convert it into a double > (PHP datatype float). This is the case for e.g. numeric(10) - values > might not fit. This is the same what PHP does when adding 1 to > LONG_MAX, for instance. If - in the procedure of doing so, strtod() > gives an ERANGE or if the length overflows EG(precision), I will > return a string.
This is exactly what I wanted to avoid. Please don't make this change.
> For "floats" > * If the length of the returned value exceeds EG(precision) or if > strtod() returns an ERANGE, I will return a string; a float otherwise.
"Thou shall only return a float if the database passes you back a float; thou shalt not convert data into the floating point type." Floats suck. If the database gives you a decimal, pass it back as a string.
> Talking about that, maybe PDO should start returning Date objects > instead of stupid string representations or sequences of numbers of > those (where users will start preg_match()ing or strtotime()ing around > if they want to do arithmetic with the returned value)...
Derick and Pierre have something in mind for the future. --Wez.

Timm Friebe

21 years ago
On Sun, 2005-02-20 at 09:44 -0500, Wez Furlong wrote:
> On Sun, 20 Feb 2005 12:36:01 +0100, Timm Friebe <thekid@thekid.de> wrote: > > * If the number does not fit, I will try to convert it into a double > > (PHP datatype float). This is the case for e.g. numeric(10) - values > > might not fit. This is the same what PHP does when adding 1 to > > LONG_MAX, for instance. If - in the procedure of doing so, strtod() > > gives an ERANGE or if the length overflows EG(precision), I will > > return a string. > > This is exactly what I wanted to avoid.
Why is that so? I think this a good idea - it saves memory in the usual case (most numbers will probably fit into a long).
> Please don't make this change.
How could I? I only have CVS karma for ext/sybase_ct, not for anything else, not Zend, not PDO:)
-- Timm If it ain't broken, it doesn't have enough features yet

Wez Furlong

21 years ago
> > On Sun, 20 Feb 2005 12:36:01 +0100, Timm Friebe <thekid@thekid.de> wrote: > > > * If the number does not fit, I will try to convert it into a double > > > (PHP datatype float). This is the case for e.g. numeric(10) - values > > > might not fit. This is the same what PHP does when adding 1 to > > > LONG_MAX, for instance. If - in the procedure of doing so, strtod() > > > gives an ERANGE or if the length overflows EG(precision), I will > > > return a string. > > > > This is exactly what I wanted to avoid. > > Why is that so? I think this a good idea - it saves memory in the usual > case (most numbers will probably fit into a long).
The problem is for the case where the mapping is not 1:1; you end up changing a 100% precise value into a floating point "guess". String has a higher fidelity than a float, and PDO prefers hi-fi any day.
> > Please don't make this change. > > How could I? I only have CVS karma for ext/sybase_ct, not for anything > else, not Zend, not PDO:)
ack :) Well, I meant really that you shouldn't spend time on it :) --Wez.