summaryrefslogtreecommitdiff
path: root/ext/pdo_mysql/mysql_statement.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_mysql/mysql_statement.c')
-rw-r--r--ext/pdo_mysql/mysql_statement.c101
1 files changed, 52 insertions, 49 deletions
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index 0d0df4ca6d..c35657191f 100644
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -34,7 +34,6 @@
# define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_libmysql(stmt)
#endif
-
static void pdo_mysql_free_result(pdo_mysql_stmt *S)
{
if (S->result) {
@@ -52,8 +51,16 @@ static void pdo_mysql_free_result(pdo_mysql_stmt *S)
efree(S->out_length);
S->bound_result = NULL;
}
+#else
+ if (S->current_row) {
+ unsigned column_count = mysql_num_fields(S->result);
+ for (unsigned i = 0; i < column_count; i++) {
+ zval_ptr_dtor_nogc(&S->current_row[i]);
+ }
+ efree(S->current_row);
+ S->current_row = NULL;
+ }
#endif
-
mysql_free_result(S->result);
S->result = NULL;
}
@@ -104,12 +111,6 @@ static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
}
}
-#ifdef PDO_USE_MYSQLND
- if (!S->stmt && S->current_data) {
- mnd_free(S->current_data);
- }
-#endif /* PDO_USE_MYSQLND */
-
efree(S);
PDO_DBG_RETURN(1);
}
@@ -317,7 +318,7 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
PDO_DBG_RETURN(pdo_mysql_stmt_execute_prepared(stmt));
}
- if (mysql_real_query(H->server, stmt->active_query_string, stmt->active_query_stringlen) != 0) {
+ if (mysql_real_query(H->server, ZSTR_VAL(stmt->active_query_string), ZSTR_LEN(stmt->active_query_string)) != 0) {
pdo_mysql_error_stmt(stmt);
PDO_DBG_RETURN(0);
}
@@ -554,7 +555,7 @@ static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori
}
#ifdef PDO_USE_MYSQLND
- zend_bool fetched_anything;
+ bool fetched_anything;
PDO_DBG_ENTER("pdo_mysql_stmt_fetch");
PDO_DBG_INF_FMT("stmt=%p", S->stmt);
@@ -567,9 +568,24 @@ static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori
PDO_DBG_RETURN(1);
}
- if (!S->stmt && S->current_data) {
- mnd_free(S->current_data);
+ zval *row_data;
+ if (mysqlnd_fetch_row_zval(S->result, &row_data, &fetched_anything) == FAIL) {
+ pdo_mysql_error_stmt(stmt);
+ PDO_DBG_RETURN(0);
+ }
+
+ if (!fetched_anything) {
+ PDO_DBG_RETURN(0);
}
+
+ if (!S->current_row) {
+ S->current_row = ecalloc(sizeof(zval), stmt->column_count);
+ }
+ for (unsigned i = 0; i < stmt->column_count; i++) {
+ zval_ptr_dtor_nogc(&S->current_row[i]);
+ ZVAL_COPY_VALUE(&S->current_row[i], &row_data[i]);
+ }
+ PDO_DBG_RETURN(1);
#else
int ret;
@@ -591,7 +607,6 @@ static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori
PDO_DBG_RETURN(1);
}
-#endif /* PDO_USE_MYSQLND */
if ((S->current_data = mysql_fetch_row(S->result)) == NULL) {
if (!S->H->buffered && mysql_errno(S->H->server)) {
@@ -602,6 +617,7 @@ static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori
S->current_lengths = mysql_fetch_lengths(S->result);
PDO_DBG_RETURN(1);
+#endif /* PDO_USE_MYSQLND */
}
/* }}} */
@@ -642,21 +658,13 @@ static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
cols[i].precision = S->fields[i].decimals;
cols[i].maxlen = S->fields[i].length;
-
-#ifdef PDO_USE_MYSQLND
- if (S->stmt) {
- cols[i].param_type = PDO_PARAM_ZVAL;
- } else
-#endif
- {
- cols[i].param_type = PDO_PARAM_STR;
- }
}
PDO_DBG_RETURN(1);
}
/* }}} */
-static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_t *len, int *caller_frees) /* {{{ */
+static int pdo_mysql_stmt_get_col(
+ pdo_stmt_t *stmt, int colno, zval *result, enum pdo_param_type *type) /* {{{ */
{
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
@@ -666,46 +674,41 @@ static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_
PDO_DBG_RETURN(0);
}
- /* With mysqlnd data is stored inside mysqlnd, not S->current_data */
- if (!S->stmt) {
- if (S->current_data == NULL || !S->result) {
- PDO_DBG_RETURN(0);
- }
- }
-
if (colno >= stmt->column_count) {
/* error invalid column */
PDO_DBG_RETURN(0);
}
#ifdef PDO_USE_MYSQLND
if (S->stmt) {
- Z_TRY_ADDREF(S->stmt->data->result_bind[colno].zv);
- *ptr = (char*)&S->stmt->data->result_bind[colno].zv;
- *len = sizeof(zval);
- PDO_DBG_RETURN(1);
+ ZVAL_COPY(result, &S->stmt->data->result_bind[colno].zv);
+ } else {
+ ZVAL_COPY(result, &S->current_row[colno]);
}
+ PDO_DBG_RETURN(1);
#else
if (S->stmt) {
if (S->out_null[colno]) {
- *ptr = NULL;
- *len = 0;
PDO_DBG_RETURN(1);
}
- *ptr = S->bound_result[colno].buffer;
- if (S->out_length[colno] > S->bound_result[colno].buffer_length) {
+
+ size_t length = S->out_length[colno];
+ if (length > 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];
- PDO_DBG_RETURN(0);
+ length = S->out_length[colno] = S->bound_result[colno].buffer_length;
}
- *len = S->out_length[colno];
+ ZVAL_STRINGL_FAST(result, S->bound_result[colno].buffer, length);
PDO_DBG_RETURN(1);
}
-#endif
- *ptr = S->current_data[colno];
- *len = S->current_lengths[colno];
+
+ if (S->current_data == NULL) {
+ PDO_DBG_RETURN(0);
+ }
+ if (S->current_data[colno]) {
+ ZVAL_STRINGL_FAST(result, S->current_data[colno], S->current_lengths[colno]);
+ }
PDO_DBG_RETURN(1);
+#endif
} /* }}} */
static char *type_to_name_native(int type) /* {{{ */
@@ -802,7 +805,7 @@ static int pdo_mysql_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *retu
add_assoc_string(return_value, "native_type", str);
}
-#ifdef PDO_USE_MYSQLND
+ enum pdo_param_type param_type;
switch (F->type) {
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_YEAR:
@@ -813,13 +816,13 @@ static int pdo_mysql_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *retu
#if SIZEOF_ZEND_LONG==8
case MYSQL_TYPE_LONGLONG:
#endif
- add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT);
+ param_type = PDO_PARAM_INT;
break;
default:
- add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
+ param_type = PDO_PARAM_STR;
break;
}
-#endif
+ add_assoc_long(return_value, "pdo_type", param_type);
add_assoc_zval(return_value, "flags", &flags);
add_assoc_string(return_value, "table", (char *) (F->table?F->table : ""));