====== 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 [[https://github.com/php/php-src/blob/master/ext/pdo/php_pdo_driver.h#L51|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 [[https://www.postgresql.org/docs/9.6/static/libpq-exec.html|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 [[https://www.sqlite.org/c3ref/bind_blob.html|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]]