rfc:pdo_float_type

PHP 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

References

rfc/pdo_float_type.txt · Last modified: 2019/05/07 15:03 by adambaratz