mirror of
https://github.com/php/php-src.git
synced 2025-01-19 02:03:47 +08:00
Fix #80027 Terrible performance using $query->fetch on queries with many bind parameters
Added new flags that allow skipping param_evt(s) that are not used by drivers, in a backwards and forward compatible manner. Updated the pgsql, mysql, sqlite and oci drivers to properly use the new flags. I've left out pdo_dblib, which doesn't have a param_hook, and pdo_firebird, which seems to be using PARAM_EVT_NORMALIZE in a wrong context (param type vs event type).
This commit is contained in:
parent
ad750c3bb6
commit
44ade0e875
4
NEWS
4
NEWS
@ -14,6 +14,10 @@ PHP NEWS
|
||||
. Fixed bug #80002 (calc free space for new interned string is wrong).
|
||||
(t-matsuno)
|
||||
|
||||
- PDO:
|
||||
. Fixed bug #80027 (Terrible performance using $query->fetch on queries with
|
||||
many bind parameters (Matteo)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #79986 (str_ireplace bug with diacritics characters). (cmb)
|
||||
|
||||
|
@ -163,6 +163,10 @@ static int dispatch_param_event(pdo_stmt_t *stmt, enum pdo_param_event event_typ
|
||||
struct pdo_bound_param_data *param;
|
||||
HashTable *ht;
|
||||
|
||||
if (stmt->dbh->skip_param_evt & (1 << event_type)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!stmt->methods->param_hook) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -468,9 +468,12 @@ struct _pdo_dbh_t {
|
||||
/* when set, convert int/floats to strings */
|
||||
unsigned stringify:1;
|
||||
|
||||
/* bitmap for pdo_param_event(s) to skip in dispatch_param_event */
|
||||
unsigned skip_param_evt:7;
|
||||
|
||||
/* the sum of the number of bits here and the bit fields preceding should
|
||||
* equal 32 */
|
||||
unsigned _reserved_flags:21;
|
||||
unsigned _reserved_flags:14;
|
||||
|
||||
/* data source string used to open this handle */
|
||||
const char *data_source;
|
||||
|
@ -617,6 +617,13 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
|
||||
|
||||
dbh->driver_data = H;
|
||||
|
||||
dbh->skip_param_evt =
|
||||
1 << PDO_PARAM_EVT_FREE |
|
||||
1 << PDO_PARAM_EVT_EXEC_POST |
|
||||
1 << PDO_PARAM_EVT_FETCH_PRE |
|
||||
1 << PDO_PARAM_EVT_FETCH_POST |
|
||||
1 << PDO_PARAM_EVT_NORMALIZE;
|
||||
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
H->max_buffer_size = 1024*1024;
|
||||
#endif
|
||||
|
@ -674,6 +674,11 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
dbh->driver_data = H;
|
||||
|
||||
dbh->skip_param_evt =
|
||||
1 << PDO_PARAM_EVT_FETCH_PRE |
|
||||
1 << PDO_PARAM_EVT_FETCH_POST |
|
||||
1 << PDO_PARAM_EVT_NORMALIZE;
|
||||
|
||||
H->prefetch = PDO_OCI_PREFETCH_DEFAULT;
|
||||
|
||||
/* allocate an environment */
|
||||
|
@ -1198,6 +1198,11 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
|
||||
H = pecalloc(1, sizeof(pdo_pgsql_db_handle), dbh->is_persistent);
|
||||
dbh->driver_data = H;
|
||||
|
||||
dbh->skip_param_evt =
|
||||
1 << PDO_PARAM_EVT_EXEC_POST |
|
||||
1 << PDO_PARAM_EVT_FETCH_PRE |
|
||||
1 << PDO_PARAM_EVT_FETCH_POST;
|
||||
|
||||
H->einfo.errcode = 0;
|
||||
H->einfo.errmsg = NULL;
|
||||
|
||||
|
@ -399,7 +399,7 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (param->is_param) {
|
||||
} else if (param->is_param && event_type == PDO_PARAM_EVT_NORMALIZE) {
|
||||
/* We need to manually convert to a pg native boolean value */
|
||||
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
|
||||
((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
|
||||
|
@ -797,6 +797,9 @@ static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{
|
||||
H->einfo.errmsg = NULL;
|
||||
dbh->driver_data = H;
|
||||
|
||||
/* skip all but this one param event */
|
||||
dbh->skip_param_evt = 0x7F ^ (1 << PDO_PARAM_EVT_EXEC_PRE);
|
||||
|
||||
filename = make_filename_safe(dbh->data_source);
|
||||
|
||||
if (!filename) {
|
||||
|
Loading…
Reference in New Issue
Block a user