Edit report at https://bugs.php.net/bug.php?id=46408&edit=1
ID: 46408 Comment by: claude dot pache at gmail dot com Reported by: alec at smecher dot bc dot ca Summary: Locale number format settings can cause pg_query_params to break with numerics Status: Wont fix Type: Bug Package: PostgreSQL related Operating System: * PHP Version: 5.*, 6 Assigned To: yohgaki Block user comment: N Private report: N New Comment: @yohgaki (and others) I think that, the root of the problem is the way PHP uses the locale information, which I consider deeply broken. Here are the details: In my understanding, the locale information is useful only for *output*, i.e. for messages destined to the user. They should not be used for any internal conversion from one type to the other, unless the result is destined to output. The problem is, that PHP uses the locale for any automatic conversion from number to string. This behaviour is ok in the following case: echo "Three and a half is: " . $number; However, in the following cases, this is NOT correct, because the resulting string must not be localised: * constructing a JSON object (I hope that json_encode() does NOT use internal number-to-string conversion); * using bcmath package (I have personnaly be bitten by this misfeature); * construct a SQL request (the present case); * etc. In all these cases, you have to do one of the following options: (1) never use any locale other than en_US (and re-implement manually the locale feature); (2) carefully check the type of each and every parameter and explicitely perform a correct conversion when needed, e.g. using number_format(..., '.', ''); (3) fix PHP to NOT use locale for number-to-string conversion unless it is explicitely asked for (side note: historically, there has been a similar problem with the "magic quote" misfeature); (4) modify the modules bcmath, postgresql, etc, so that they circumvent the mentionned PHP misfeature, i.e., they do the option (2) above at your place. In my dreams, the option (3) would be implemented, but pragmatically, I think that option (4) has more chance to be implemented rapidly, if ever. I think that alec asked precisely the option (4) to be implemented. (Personnally, I have opted for option (1).) Claude P.S. The option (4) might seem a non-optimal hack. However, do not forget that programming languages and API should be adapted to the needs of the programmers, and not the other way round. Previous Comments: ------------------------------------------------------------------------ [2012-04-18 03:13:12] yohg...@php.net You misunderstand how libpq/PostgreSQL works. If you think you can make proper patch for this, clone git source and send pull request. No one will stop you from that. ------------------------------------------------------------------------ [2012-04-18 02:58:26] alec at smecher dot bc dot ca I believe pg_query_params is broken until this is resolved, but it looks like we're not going to agree on it. I hope someone else can speak up if they do think this is a bug. Since we disagree on the approach any patch I write to correct it will be rejected. I'll add a comment to the manual page for pg_query_params to document this. ------------------------------------------------------------------------ [2012-04-18 02:26:48] yohg...@php.net BTW, you are reading PostgreSQL manual wrong. libpq's functions never care about data types, but the server is. If you are curious still, try to make patch that meets the requirement I've wrote. ------------------------------------------------------------------------ [2012-04-18 02:19:38] yohg...@php.net IIRC, MDB2 cares data types. (which I think it's a design problem for loosely type langs.) Therefore, it may change behavior according to locale. Anyway, It's not a matter of argument. It's the way it works. As I explained repeatedly, ALL params are passed as string and types are NEVER cared in C API. To know the data type, module should issue an additional query to get meta data. Additional query for each query is severe performance hit. Therefore, it is a PHP programmer's responsibility (or Perhaps, PostgreSQL. If they would like to change behavior via client environment vars. I guess they would not.) If you could submit patch that works for all data types and does not require additional query, I'll review it. ------------------------------------------------------------------------ [2012-04-18 01:30:38] alec at smecher dot bc dot ca Your example of storing a string-formatted double in a varchar column strikes me as an unusual case involving a type mismatch, and can be worked around clearly and logically by passing "$number" in rather than $number. If this isn't going to be fixed, there should at least be documentation in the manual for pg_query_params: "If binding numeric data for use as numeric data, make sure you first cast it to a string using '.' for a decimal separator." But that makes no sense at all to me. Meanwhile, this same issue has been solved elsewhere as I've suggested. Gnome: https://bugzilla.gnome.org/show_bug.cgi?id=650016 Pear::DB: http://pear.php.net/bugs/bug.php?id=3021 It's also implemented in these other cases with specific number formatting code as I believe it should: Pear::MDB2: http://svn.php.net/viewvc/pear/packages/MDB2/trunk/MDB2/Driver/Datatype/Common.php?view=markup#l1498 mysqli: https://github.com/php/php-src/blob/master/ext/mysqli/mysqli_api.c#L102 "PostgreSQL users are supposed to pass/recieve data via strings *always* with C/C++ API." -- this is also incorrect, if I understand you properly. See the paramTypes column documented here http://www.postgresql.org/docs/9.1/static/libpq-exec.html for the PQexecParams function that you're using. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=46408 -- Edit this bug report at https://bugs.php.net/bug.php?id=46408&edit=1