Fixup LOB handling for inserts (refs #34630).

Also tripped over the return of PECL #5200; looks like mysql doesn't return an
accurate length for the columns.  The PDO driver will sanity check the real
length against the buffer size it allocated (based on the info provided by
mysql), so that we won't overrun the buffer.  In addition, if a varchar field
is reported as having a length of less than 128, we'll allocate 128 just in
case.

If the data is truncated, report it via the appropriate sqlstate code.

There must be a better way to do this stuff.
This commit is contained in:
Wez Furlong 2005-09-25 02:05:03 +00:00
parent fab0baa274
commit fdd42afa6c

View File

@ -142,6 +142,26 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
S->fields[i].max_length? S->fields[i].max_length:
S->fields[i].length;
}
#if 0
printf("%d: max_length=%d length=%d buffer_length=%d type=%d\n",
i,
S->fields[i].max_length,
S->fields[i].length,
S->bound_result[i].buffer_length,
S->fields[i].type
);
#endif
/* there are cases where the length reported by mysql is too short.
* eg: when describing a table that contains an enum column. Since
* we have no way of knowing the true length either, we'll bump up
* our buffer size to a reasonable size, just in case */
if (S->fields[i].max_length == 0 && S->bound_result[i].buffer_length < 128 && MYSQL_TYPE_VAR_STRING) {
S->bound_result[i].buffer_length = 128;
}
S->out_length[i] = 0;
S->bound_result[i].buffer = emalloc(S->bound_result[i].buffer_length);
S->bound_result[i].is_null = &S->out_null[i];
S->bound_result[i].length = &S->out_length[i];
@ -291,9 +311,24 @@ static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
}
switch (PDO_PARAM_TYPE(param->param_type)) {
case PDO_PARAM_LOB:
case PDO_PARAM_STMT:
return 0;
case PDO_PARAM_LOB:
if (Z_TYPE_P(param->parameter) == IS_RESOURCE) {
php_stream *stm;
php_stream_from_zval_no_verify(stm, &param->parameter);
if (stm) {
SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
Z_TYPE_P(param->parameter) = IS_STRING;
Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
} else {
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
return 0;
}
}
/* fall through */
default:
;
}
@ -423,6 +458,13 @@ static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsig
return 1;
}
*ptr = S->bound_result[colno].buffer;
if (S->out_length[colno] > S->bound_result[colno].buffer_length) {
/* mysql lied about the column width */
strcpy(stmt->error_code, "01004"); /* truncated */
S->out_length[colno] = S->bound_result[colno].buffer_length;
*len = S->out_length[colno];
return 0;
}
*len = S->out_length[colno];
return 1;
}