PHP RFC: PDO Float Type
- Version: 0.5
- Date: 2017-04-05
- Author: Adam Baratz adambaratz@php.net
- Status: Withdrawn
- First Published at: http://wiki.php.net/rfc/pdo_float_type
Introduction
The PDO extension does not have a type to represent floating point values.
The current recommended practice is to use PDO::PARAM_STR
. Queries formed this way produce the correct results, but with some inefficiencies. It can force unnecessary string casts on zvals, which result in extra memory allocations. If emulated prepared statements are enabled -- the default for pdo_mysql, the only option for pdo_dblib -- values will be quoted incorrectly, which results in implicit casts.
Proposal
A new type, PDO::PARAM_FLOAT
, will be added. It will indicate that a parameter can be interpreted as and presented to the database server as a floating point value. The name was selected to correspond to the PHP type system.
As indicated by the comments on pdo_param_type, each type should correspond to a C type. PHP floats are represented as doubles and the APIs used by each supported PDO driver represent floating point values as doubles, so PDO::PARAM_FLOAT
will correspond to double. This is mainly relevant for fetching column data, which is otherwise considered out of scope for this RFC (see Future Scope).
The supported PDO drivers will be modified as little as possible for this type to be supported. In fact, only pdo_sqlite will require modifications. When emulated prepared statements are enabled, these values will be interpolated in decimal form.
Changes To Supported PDO Drivers
pdo_dblib
This driver will require no modifications. It only supports emulated prepared statements. Changes to that shared code will ensure that queries are executed without implicit casts.
pdo_firebird
This driver will require no modifications. The addition of PDO::PARAM_FLOAT
will prevent floats from being cast to strings before binding them. Other values won't be cast.
The PDO_PARAM_EVT_EXEC_PRE
hook (see ext/pdo_firebird/firebird_statement.c:firebird_stmt_param_hook
) checks for double zvals. This code isn't reached because any zval doubles will be cast to other types before they reach this hook (see ext/pdo/pdo_stmt.c:really_register_bound_param
).
pdo_mysql
This driver will require no modifications. The addition of PDO::PARAM_FLOAT
will prevent floats from being cast to strings before binding them. Other values won't be cast.
The PDO_PARAM_EVT_EXEC_PRE
hook (see ext/pdo_mysql/mysql_statement.c:pdo_mysql_stmt_param_hook
) will check for double zvals. This code isn't reached because any zval doubles will be cast to other types before they reach this hook (see ext/pdo/pdo_stmt.c:really_register_bound_param
).
pdo_oci
This driver will require no modifications.
All values not bound with PDO::PARAM_LOB
are cast to strings (see ext/pdo_oci/oct_statement.c:oci_bind_input_cb
).
pdo_odbc
This driver will require no modifications.
All values not bound with PDO::PARAM_LOB
are cast to strings (see the PDO_PARAM_EVT_EXEC_PRE
hook in ext/pdo_odbc/odbc_stmt.c:odbc_stmt_param_hook
).
pdo_pgsql
This driver will require no modifications.
All values not bound with PDO::PARAM_LOB
are cast to strings. This is a requirement of the APIs for executing statements.
pdo_sqlite
This driver will require a small modification.
It currently casts values to the type implied by the PDO type so they can be bound with the most appropriate API. This behavior would be replicated for PDO::PARAM_FLOAT
.
Backward Incompatible Changes
This is entirely new functionality. Existing code will work as is.
Future Scope
Driver Modifications (Input)
pdo_oci and pdo_odbc could be modified to avoid casting values to strings. This could save a little memory churn, but this decision is best made by the maintainers of those drivers. End users shouldn't notice a difference in functionality either way.
Driver Modifications (Output)
Some drivers could be modified to return float column data as PHP floats. It's currently possible to do this -- pdo_dblib does -- so it's being considered intentional that others don't.
Fixed Precision Types
These types have different storage requirements from floats. They often vary a bit between the APIs used by supported drivers. It would be valuable for PDO to support these types, but this can be handled by a separate RFC. The documentation for PDO::PARAM_FLOAT
should state clearly that it's not intended to be used for fixed precision values. Since these values are currently bound as PDO::PARAM_STR
, the introduction of PDO::PARAM_FLOAT
shouldn't harm how they're presented to DBs.
Proposed PHP Version(s)
Next PHP 7.x.
Proposed Voting Choices
This project requires a 50%+1 majority.
Patches and Tests
- PR without tests: https://github.com/php/php-src/pull/2500
References
- Earlier discussion on this topic: https://externals.io/thread/551
- Discussion of this RFC: https://externals.io/thread/805