Merge with internal version

This commit is contained in:
Andrey Hristov 2008-01-23 19:11:28 +00:00
parent 0095544c4d
commit c52b63ea1d
16 changed files with 300 additions and 115 deletions

View File

@ -1,6 +1,9 @@
// $Id$
// vim:ft=javascript
ARG_WITH("mysqlnd", "MySQL-nd support", "no");
if (PHP_MYSQLND != "no") {
mysqld_source = "";
if (CHECK_LIB("ws2_32.lib", "mysqlnd")) {
mysqlnd_source =
@ -18,3 +21,4 @@ if (CHECK_LIB("ws2_32.lib", "mysqlnd")) {
"mysqlnd_wireprotocol.c";
EXTENSION("mysqlnd", mysqlnd_source, false);
}
}

View File

@ -67,7 +67,7 @@ MYSQLND_STATS *mysqlnd_global_stats = NULL;
static zend_bool mysqlnd_library_initted = FALSE;
enum_func_status mysqlnd_send_close(MYSQLND * conn TSRMLS_DC);
static enum_func_status mysqlnd_send_close(MYSQLND * conn TSRMLS_DC);
/* {{{ mysqlnd_library_init */
static
@ -454,11 +454,11 @@ PHPAPI void mysqlnd_end_psession(MYSQLND *conn)
/* {{{ mysqlnd_connect */
PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn,
char *host, char *user,
char *passwd, unsigned int passwd_len,
char *db, unsigned int db_len,
const char *host, const char *user,
const char *passwd, unsigned int passwd_len,
const char *db, unsigned int db_len,
unsigned int port,
char *socket,
const char *socket,
unsigned int mysql_flags,
MYSQLND_THD_ZVAL_PCACHE *zval_cache
TSRMLS_DC)
@ -949,7 +949,7 @@ MYSQLND_METHOD(mysqlnd_conn, sqlstate)(const MYSQLND * const conn)
/* {{{ mysqlnd_old_escape_string */
PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int escapestr_len TSRMLS_DC)
PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, size_t escapestr_len TSRMLS_DC)
{
DBG_ENTER("mysqlnd_old_escape_string");
DBG_RETURN(mysqlnd_cset_escape_slashes(mysqlnd_find_charset_name("latin1"),
@ -961,7 +961,7 @@ PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int
/* {{{ mysqlnd_conn::escape_string */
static ulong
MYSQLND_METHOD(mysqlnd_conn, escape_string)(const MYSQLND * const conn, char *newstr,
const char *escapestr, int escapestr_len TSRMLS_DC)
const char *escapestr, size_t escapestr_len TSRMLS_DC)
{
DBG_ENTER("mysqlnd_conn::escape_string");
DBG_INF_FMT("conn=%llu", conn->thread_id);
@ -1088,7 +1088,7 @@ MYSQLND_METHOD(mysqlnd_conn, kill)(MYSQLND *conn, unsigned int pid TSRMLS_DC)
/* }}} */
/* {{{ _mysqlnd_conn::set_charset */
/* {{{ mysqlnd_conn::set_charset */
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn, set_charset)(MYSQLND * const conn, const char * const csname TSRMLS_DC)
{
@ -1696,8 +1696,8 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
/* }}} */
/* {{{ _mysqlnd_conn::use_result */
MYSQLND_RES *
/* {{{ mysqlnd_conn::use_result */
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_conn, use_result)(MYSQLND * const conn TSRMLS_DC)
{
MYSQLND_RES *result;
@ -1729,8 +1729,8 @@ MYSQLND_METHOD(mysqlnd_conn, use_result)(MYSQLND * const conn TSRMLS_DC)
/* }}} */
/* {{{ _mysqlnd_conn::store_result */
MYSQLND_RES *
/* {{{ mysqlnd_conn::store_result */
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_conn, store_result)(MYSQLND * const conn TSRMLS_DC)
{
MYSQLND_RES *result;
@ -1762,7 +1762,7 @@ MYSQLND_METHOD(mysqlnd_conn, store_result)(MYSQLND * const conn TSRMLS_DC)
/* {{{ mysqlnd_conn::get_connection_stats */
void
static void
MYSQLND_METHOD(mysqlnd_conn, get_connection_stats)(const MYSQLND * const conn,
zval *return_value
TSRMLS_DC ZEND_FILE_LINE_DC)

View File

@ -69,11 +69,11 @@ PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_name(const char * const char
#define mysqlnd_init(persistent) _mysqlnd_init((persistent) TSRMLS_CC)
PHPAPI MYSQLND * _mysqlnd_init(zend_bool persistent TSRMLS_DC);
PHPAPI MYSQLND * mysqlnd_connect(MYSQLND *conn,
char *host, char *user,
char *passwd, unsigned int passwd_len,
char *db, unsigned int db_len,
const char *host, const char *user,
const char *passwd, unsigned int passwd_len,
const char *db, unsigned int db_len,
unsigned int port,
char *socket,
const char *socket,
unsigned int mysql_flags,
MYSQLND_THD_ZVAL_PCACHE *zval_cache
TSRMLS_DC);
@ -85,6 +85,7 @@ void _mysqlnd_debug(const char *mode TSRMLS_DC);
/* Query */
#define mysqlnd_fetch_into(result, flags, ret_val, ext) (result)->m.fetch_into((result), (flags), (ret_val), (ext) TSRMLS_CC ZEND_FILE_LINE_CC)
#define mysqlnd_fetch_row_c(result) (result)->m.fetch_row_c((result) TSRMLS_CC)
#define mysqlnd_fetch_all(result, flags, return_value) (result)->m.fetch_all((result), (flags), (return_value) TSRMLS_CC ZEND_FILE_LINE_CC)
#define mysqlnd_result_fetch_field_data(res,offset,ret) (res)->m.fetch_field_data((res), (offset), (ret) TSRMLS_CC)
#define mysqlnd_get_connection_stats(conn, values) (conn)->m->get_statistics((conn), (values) TSRMLS_CC ZEND_FILE_LINE_CC)
@ -235,7 +236,7 @@ PHPAPI void mysqlnd_set_local_infile_handler(MYSQLND * const conn, const char *
#define mysqlnd_escape_string(newstr, escapestr, escapestr_len) \
mysqlnd_old_escape_string((newstr), (escapestr), (escapestr_len) TSRMLS_CC)
PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int escapestr_len TSRMLS_DC);
PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, size_t escapestr_len TSRMLS_DC);
/* PS */
@ -247,10 +248,10 @@ PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int
#define mysqlnd_stmt_execute(stmt) (stmt)->m->execute((stmt) TSRMLS_CC)
#define mysqlnd_stmt_send_long_data(s,p,d,l) (s)->m->send_long_data((s), (p), (d), (l) TSRMLS_CC)
#define mysqlnd_stmt_bind_param(stmt,bind) (stmt)->m->bind_param((stmt), (bind) TSRMLS_CC)
#define mysqlnd_stmt_refresh_bind_param(s) (s)->m->refresh_bind_param((s) TSRMLS_CC)
#define mysqlnd_stmt_bind_result(stmt,bind) (stmt)->m->bind_result((stmt), (bind) TSRMLS_CC)
#define mysqlnd_stmt_param_metadata(stmt) (stmt)->m->get_parameter_metadata((stmt))
#define mysqlnd_stmt_result_metadata(stmt) (stmt)->m->get_result_metadata((stmt) TSRMLS_CC)
#define mysqlnd_stmt_ronly_result_metadata(stmt) ((stmt)->result)
#define mysqlnd_stmt_free_result(stmt) (stmt)->m->free_result((stmt) TSRMLS_CC)
#define mysqlnd_stmt_close(stmt, implicit) (stmt)->m->dtor((stmt), (implicit) TSRMLS_CC)

View File

@ -463,7 +463,7 @@ PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_name(const char * const name
/* {{{ mysqlnd_cset_escape_quotes */
PHPAPI ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const cset, char *newstr,
const char *escapestr, int escapestr_len TSRMLS_DC)
const char *escapestr, size_t escapestr_len TSRMLS_DC)
{
const char *newstr_s = newstr;
const char *newstr_e = newstr + 2 * escapestr_len;
@ -517,7 +517,7 @@ PHPAPI ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const cset, char
/* {{{ mysqlnd_cset_escape_slashes */
PHPAPI ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char *newstr,
const char *escapestr, int escapestr_len TSRMLS_DC)
const char *escapestr, size_t escapestr_len TSRMLS_DC)
{
const char *newstr_s = newstr;
const char *newstr_e = newstr + 2 * escapestr_len;

View File

@ -22,10 +22,10 @@
#define MYSQLND_CHARSET_H
PHPAPI ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const charset, char *newstr,
const char *escapestr, int escapestr_len TSRMLS_DC);
const char *escapestr, size_t escapestr_len TSRMLS_DC);
PHPAPI ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char *newstr,
const char *escapestr, int escapestr_len TSRMLS_DC);
const char *escapestr, size_t escapestr_len TSRMLS_DC);
#endif /* MYSQLND_CHARSET_H */

View File

@ -28,7 +28,7 @@
#define MYSQL_STMT MYSQLND_STMT
#define MYSQL_FIELD MYSQLND_FIELD
#define MYSQL_RES MYSQLND_RES
#define MYSQL_ROW MYSQLND_ROW
#define MYSQL_ROW MYSQLND_ROW_C
#define MYSQL MYSQLND
#define my_bool zend_bool
#define my_ulonglong uint64
@ -58,7 +58,7 @@
#define mysql_fetch_field(r) mysqlnd_fetch_field((r))
#define mysql_fetch_field_direct(r,o) mysqlnd_fetch_field_direct((r), (o))
#define mysql_fetch_lengths(r) mysqlnd_fetch_lengths((r))
#define mysql_fetch_row(r) mysqlnd_fetch_row((r))
#define mysql_fetch_row(r) mysqlnd_fetch_row_c((r))
#define mysql_field_count(r) mysqlnd_field_count((r))
#define mysql_field_seek(r,o) mysqlnd_field_seek((r), (o))
#define mysql_field_tell(r) mysqlnd_field_tell((r))

View File

@ -118,7 +118,7 @@ int mysqlnd_local_infile_error(void *ptr, char *error_buf, uint error_buf_len TS
DBG_RETURN(info->error_no);
}
strncpy(error_buf, "Unknown error", error_buf_len);
strlcpy(error_buf, "Unknown error", error_buf_len);
DBG_INF_FMT("no info, %d", CR_UNKNOWN_ERROR);
DBG_RETURN(CR_UNKNOWN_ERROR);
}

View File

@ -294,9 +294,11 @@ void *mysqlnd_palloc_get_zval(MYSQLND_THD_ZVAL_PCACHE * const thd_cache, zend_bo
void *ret = NULL;
DBG_ENTER("mysqlnd_palloc_get_zval");
DBG_INF_FMT("cache=%p *last_added=%p free_items=%d",
thd_cache, thd_cache? thd_cache->parent->free_list.last_added:NULL,
thd_cache->parent->free_items);
if (thd_cache) {
DBG_INF_FMT("cache=%p *last_added=%p free_items=%d",
thd_cache, thd_cache->parent->free_list.last_added,
thd_cache->parent->free_items);
}
if (thd_cache) {
MYSQLND_ZVAL_PCACHE *cache = thd_cache->parent;
@ -343,11 +345,13 @@ void mysqlnd_palloc_zval_ptr_dtor(zval **zv, MYSQLND_THD_ZVAL_PCACHE * const thd
{
MYSQLND_ZVAL_PCACHE *cache;
DBG_ENTER("mysqlnd_palloc_zval_ptr_dtor");
DBG_INF_FMT("cache=%p parent_block=%p last_in_block=%p *zv=%p refc=%d type=%d ",
thd_cache,
thd_cache->parent? thd_cache->parent->block:NULL,
thd_cache->parent? thd_cache->parent->last_in_block:NULL,
*zv, Z_REFCOUNT_PP(zv), type);
if (thd_cache) {
DBG_INF_FMT("cache=%p parent_block=%p last_in_block=%p *zv=%p refc=%d type=%d ",
thd_cache,
thd_cache->parent->block,
thd_cache->parent->last_in_block,
*zv, Z_REFCOUNT_PP(zv), type);
}
*copy_ctor_called = FALSE;
/* Check whether cache is used and the zval is from the cache */
if (!thd_cache || !(cache = thd_cache->parent) || ((char *)*zv < (char *)thd_cache->parent->block ||

View File

@ -325,7 +325,7 @@ typedef union {
(((uint32) ((uchar) (A)[3])) << 24))
#define uint8korr(A) ((ulonglong)(((uint32) (((uchar*) (A))[7])) +\
#define bit_uint8korr(A) ((ulonglong)(((uint32) (((uchar*) (A))[7])) +\
(((uint32) (((uchar*) (A))[6])) << 8) +\
(((uint32) (((uchar*) (A))[5])) << 16) +\
(((uint32) (((uchar*) (A))[4])) << 24)) +\

View File

@ -149,8 +149,8 @@
#define SET_CLIENT_ERROR(error_info, a, b, c) \
{ \
error_info.error_no = a; \
strncpy(error_info.sqlstate, b, sizeof(error_info.sqlstate)); \
strncpy(error_info.error, c, sizeof(error_info.error)); \
strlcpy(error_info.sqlstate, b, sizeof(error_info.sqlstate)); \
strlcpy(error_info.error, c, sizeof(error_info.error)); \
}
#define SET_STMT_ERROR(stmt, a, b, c) SET_CLIENT_ERROR(stmt->error_info, a, b, c)

View File

@ -331,7 +331,9 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const stmt, const char * co
no metadata at prepare.
*/
if (stmt_to_prepare->field_count) {
MYSQLND_RES *result = mysqlnd_result_init(stmt_to_prepare->field_count, NULL TSRMLS_CC);
MYSQLND_RES *result = mysqlnd_result_init(stmt_to_prepare->field_count,
mysqlnd_palloc_get_thd_cache_reference(stmt->conn->zval_cache)
TSRMLS_CC);
/* Allocate the result now as it is needed for the reading of metadata */
stmt_to_prepare->result = result;
@ -731,37 +733,16 @@ MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT *stmt TSRMLS_DC)
}
SET_EMPTY_ERROR(stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info);
MYSQLND_INC_CONN_STATISTIC(&stmt->conn->stats, STAT_PS_UNBUFFERED_SETS);
result = stmt->result;
result = stmt->result;
result->type = MYSQLND_RES_PS_UNBUF;
result->m.fetch_row = stmt->cursor_exists? mysqlnd_fetch_stmt_row_cursor:
mysqlnd_stmt_fetch_row_unbuffered;
result->m.fetch_lengths = NULL; /* makes no sense */
result->zval_cache = mysqlnd_palloc_get_thd_cache_reference(conn->zval_cache);
result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
DBG_INF_FMT("cursor=%d zval_cache=%p", stmt->cursor_exists, result->zval_cache);
/*
Will be freed in the mysqlnd_internal_free_result_contents() called
by the resource destructor. mysqlnd_fetch_row_unbuffered() expects
this to be not NULL.
*/
PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);
result->row_packet->field_count = result->field_count;
result->row_packet->binary_protocol = TRUE;
result->row_packet->fields_metadata = stmt->result->meta->fields;
result->row_packet->bit_fields_count = result->meta->bit_fields_count;
result->row_packet->bit_fields_total_len = result->meta->bit_fields_total_len;
result->lengths = NULL;
result->m.use_result(stmt->result, TRUE TSRMLS_CC);
result->m.fetch_row = stmt->cursor_exists? mysqlnd_fetch_stmt_row_cursor:
mysqlnd_stmt_fetch_row_unbuffered;
stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED;
/* No multithreading issues as we don't share the connection :) */
DBG_INF_FMT("%p", result);
DBG_RETURN(result);
}
@ -1164,6 +1145,31 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_param)(MYSQLND_STMT * const stmt,
/* }}} */
/* {{{ _mysqlnd_stmt_refresh_bind_param */
static enum_func_status
MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const stmt TSRMLS_DC)
{
DBG_ENTER("mysqlnd_stmt::refresh_bind_param");
DBG_INF_FMT("stmt=%lu param_count=%u", stmt->stmt_id, stmt->param_count);
if (stmt->state < MYSQLND_STMT_PREPARED) {
SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared);
DBG_ERR("not prepared");
DBG_RETURN(FAIL);
}
SET_EMPTY_ERROR(stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info);
if (stmt->param_count) {
stmt->send_types_to_server = 1;
}
DBG_INF("PASS");
DBG_RETURN(PASS);
}
/* }}} */
/* {{{ mysqlnd_stmt::bind_result */
static enum_func_status
MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt,
@ -1535,7 +1541,7 @@ void mysqlnd_internal_free_stmt_content(MYSQLND_STMT *stmt TSRMLS_DC)
/* Destroy the input bind */
if (stmt->param_bind) {
int i;
unsigned int i;
/*
Because only the bound variables can point to our internal buffers, then
separate or free only them. Free is possible because the user could have
@ -1651,7 +1657,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, dtor)(MYSQLND_STMT * const stmt, zend_bool
{
enum_func_status ret;
DBG_ENTER("mysqlnd_stmt::close");
DBG_ENTER("mysqlnd_stmt::dtor");
DBG_INF_FMT("stmt=%p", stmt);
MYSQLND_INC_GLOBAL_STATISTIC(implicit == TRUE? STAT_STMT_CLOSE_IMPLICIT:
@ -1683,6 +1689,7 @@ struct st_mysqlnd_stmt_methods mysqlnd_stmt_methods = {
MYSQLND_METHOD(mysqlnd_stmt, fetch),
MYSQLND_METHOD(mysqlnd_stmt, bind_param),
MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param),
MYSQLND_METHOD(mysqlnd_stmt, bind_result),
MYSQLND_METHOD(mysqlnd_stmt, send_long_data),
MYSQLND_METHOD(mysqlnd_stmt, param_metadata),

View File

@ -438,7 +438,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
static
unsigned long * mysqlnd_fetch_lengths_buffered(MYSQLND_RES * const result)
{
int i;
unsigned int i;
zval **previous_row;
/*
@ -481,6 +481,102 @@ PHPAPI unsigned long * mysqlnd_fetch_lengths(MYSQLND_RES * const result)
/* }}} */
/* {{{ mysqlnd_fetch_row_unbuffered_c */
static MYSQLND_ROW_C
mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES *result TSRMLS_DC)
{
enum_func_status ret;
MYSQLND_ROW_C retrow = NULL;
unsigned int i,
field_count = result->field_count;
php_mysql_packet_row *row_packet = result->row_packet;
unsigned long *lengths = result->lengths;
DBG_ENTER("mysqlnd_fetch_row_unbuffered");
if (result->unbuf->eof_reached) {
/* No more rows obviously */
DBG_RETURN(retrow);
}
if (result->conn->state != CONN_FETCHING_DATA) {
SET_CLIENT_ERROR(result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC,
UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_RETURN(retrow);
}
/* Let the row packet fill our buffer and skip additional mnd_malloc + memcpy */
row_packet->skip_extraction = FALSE;
/*
If we skip rows (row == NULL) we have to
mysqlnd_unbuffered_free_last_data() before it. The function returns always true.
*/
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) {
MYSQLND_FIELD *field = result->meta->fields;
result->unbuf->row_count++;
retrow = mnd_malloc(result->field_count * sizeof(char *));
mysqlnd_unbuffered_free_last_data(result TSRMLS_CC);
result->unbuf->last_row_data = row_packet->fields;
result->unbuf->last_row_buffer = row_packet->row_buffer;
row_packet->fields = NULL;
row_packet->row_buffer = NULL;
MYSQLND_INC_CONN_STATISTIC(&result->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_UNBUF);
for (i = 0; i < field_count; i++, field++) {
zval *data = result->unbuf->last_row_data[i];
int len;
if (Z_TYPE_P(data) != IS_NULL) {
convert_to_string(data);
retrow[i] = Z_STRVAL_P(data);
len = Z_STRLEN_P(data);
} else {
retrow[i] = NULL;
len = 0;
}
if (lengths) {
lengths[i] = len;
}
if (field->max_length < len) {
field->max_length = len;
}
}
} else if (ret == FAIL) {
if (row_packet->error_info.error_no) {
result->conn->error_info = row_packet->error_info;
DBG_ERR_FMT("errorno=%d error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
}
result->conn->state = CONN_READY;
result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
} else if (row_packet->eof) {
/* Mark the connection as usable again */
DBG_INF_FMT("warns=%u status=%u", row_packet->warning_count, row_packet->server_status);
result->unbuf->eof_reached = TRUE;
result->conn->upsert_status.warning_count = row_packet->warning_count;
result->conn->upsert_status.server_status = row_packet->server_status;
/*
result->row_packet will be cleaned when
destroying the result object
*/
if (result->conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) {
result->conn->state = CONN_NEXT_RESULT_PENDING;
} else {
result->conn->state = CONN_READY;
}
mysqlnd_unbuffered_free_last_data(result TSRMLS_CC);
}
DBG_RETURN(retrow);
}
/* }}} */
/* {{{ mysqlnd_fetch_row_unbuffered */
static enum_func_status
mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flags,
@ -528,11 +624,12 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag
if (!row_packet->skip_extraction) {
HashTable *row_ht = Z_ARRVAL_P(row);
MYSQLND_FIELD *field = result->meta->fields;
struct mysqlnd_field_hash_key *zend_hash_key = result->meta->zend_hash_keys;
for (i = 0; i < field_count; i++) {
for (i = 0; i < field_count; i++, field++, zend_hash_key++) {
zval *data = result->unbuf->last_row_data[i];
int len = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data);
MYSQLND_RES_METADATA *meta = result->meta;
if (lengths) {
lengths[i] = len;
@ -555,31 +652,31 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag
the index is a numeric and convert it to it. This however means constant
hashing of the column name, which is not needed as it can be precomputed.
*/
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
if (zend_hash_key->is_numeric == FALSE) {
#if PHP_MAJOR_VERSION >= 6
if (UG(unicode)) {
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
meta->zend_hash_keys[i].ustr,
meta->zend_hash_keys[i].ulen + 1,
meta->zend_hash_keys[i].key,
zend_hash_key->ustr,
zend_hash_key->ulen + 1,
zend_hash_key->key,
(void *) &data, sizeof(zval *), NULL);
} else
#endif
{
zend_hash_quick_update(Z_ARRVAL_P(row),
meta->fields[i].name,
meta->fields[i].name_length + 1,
meta->zend_hash_keys[i].key,
field->name,
field->name_length + 1,
zend_hash_key->key,
(void *) &data, sizeof(zval *), NULL);
}
} else {
zend_hash_index_update(Z_ARRVAL_P(row),
meta->zend_hash_keys[i].key,
zend_hash_key->key,
(void *) &data, sizeof(zval *), NULL);
}
}
if (meta->fields[i].max_length < len) {
meta->fields[i].max_length = len;
if (field->max_length < len) {
field->max_length = len;
}
}
}
@ -617,16 +714,27 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag
/* {{{ mysqlnd_res::use_result */
MYSQLND_RES *
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, zend_bool ps TSRMLS_DC)
{
DBG_ENTER("mysqlnd_res::use_result");
DBG_INF_FMT("ps=%d", ps);
result->type = MYSQLND_RES_NORMAL;
result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
result->m.fetch_lengths = mysqlnd_fetch_lengths_unbuffered;
result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
SET_EMPTY_ERROR(result->conn->error_info);
if (ps == FALSE) {
result->type = MYSQLND_RES_NORMAL;
result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
result->m.fetch_lengths = mysqlnd_fetch_lengths_unbuffered;
result->lengths = mnd_ecalloc(result->field_count, sizeof(unsigned long));
} else {
result->type = MYSQLND_RES_PS_UNBUF;
/* result->m.fetch_row() will be set in mysqlnd_ps.c */
result->m.fetch_lengths = NULL; /* makes no sense */
result->lengths = NULL;
}
result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
/*
Will be freed in the mysqlnd_internal_free_result_contents() called
@ -635,19 +743,52 @@ MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, zend_bool ps
*/
PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);
result->row_packet->field_count = result->field_count;
result->row_packet->binary_protocol = FALSE;
result->row_packet->binary_protocol = ps;
result->row_packet->fields_metadata = result->meta->fields;
result->row_packet->bit_fields_count = result->meta->bit_fields_count;
result->row_packet->bit_fields_total_len = result->meta->bit_fields_total_len;
result->lengths = mnd_ecalloc(result->field_count, sizeof(unsigned long));
/* No multithreading issues as we don't share the connection :) */
DBG_RETURN(result);
}
/* }}} */
/* {{{ mysqlnd_fetch_row_buffered_c */
static MYSQLND_ROW_C
mysqlnd_fetch_row_buffered_c(MYSQLND_RES *result TSRMLS_DC)
{
MYSQLND_ROW_C ret = NULL;
unsigned int i;
DBG_ENTER("mysqlnd_fetch_row_buffered_c");
/* If we haven't read everything */
if (result->data->data_cursor &&
(result->data->data_cursor - result->data->data) < result->data->row_count)
{
ret = mnd_malloc(result->field_count * sizeof(char *));
zval **current_row = *result->data->data_cursor;
for (i = 0; i < result->field_count; i++) {
zval *data = current_row[i];
if (Z_TYPE_P(data) != IS_NULL) {
convert_to_string(data);
ret[i] = Z_STRVAL_P(data);
} else {
ret[i] = NULL;
}
}
result->data->data_cursor++;
MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF);
} else {
result->data->data_cursor = NULL;
DBG_INF("EOF reached");
}
DBG_RETURN(ret);
}
/* }}} */
/* {{{ mysqlnd_fetch_row_buffered */
static enum_func_status
mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags,
@ -664,7 +805,10 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags,
(result->data->data_cursor - result->data->data) < result->data->row_count)
{
zval **current_row = *result->data->data_cursor;
for (i = 0; i < result->field_count; i++) {
MYSQLND_FIELD *field = result->meta->fields;
struct mysqlnd_field_hash_key *zend_hash_key = result->meta->zend_hash_keys;
for (i = 0; i < result->field_count; i++, field++, zend_hash_key++) {
zval *data = current_row[i];
/*
@ -687,26 +831,26 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags,
the index is a numeric and convert it to it. This however means constant
hashing of the column name, which is not needed as it can be precomputed.
*/
if (result->meta->zend_hash_keys[i].is_numeric == FALSE) {
if (zend_hash_key->is_numeric == FALSE) {
#if PHP_MAJOR_VERSION >= 6
if (UG(unicode)) {
zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
result->meta->zend_hash_keys[i].ustr,
result->meta->zend_hash_keys[i].ulen + 1,
result->meta->zend_hash_keys[i].key,
zend_hash_key->ustr,
zend_hash_key->ulen + 1,
zend_hash_key->key,
(void *) &data, sizeof(zval *), NULL);
} else
#endif
{
zend_hash_quick_update(Z_ARRVAL_P(row),
result->meta->fields[i].name,
result->meta->fields[i].name_length + 1,
result->meta->zend_hash_keys[i].key,
field->name,
field->name_length + 1,
zend_hash_key->key,
(void *) &data, sizeof(zval *), NULL);
}
} else {
zend_hash_index_update(Z_ARRVAL_P(row),
result->meta->zend_hash_keys[i].key,
zend_hash_key->key,
(void *) &data, sizeof(zval *), NULL);
}
}
@ -761,7 +905,7 @@ mysqlnd_store_result_fetch_data(MYSQLND * const conn, MYSQLND_RES *result,
row_packet.bit_fields_total_len = meta->bit_fields_total_len;
/* Let the row packet fill our buffer and skip additional malloc + memcpy */
while (FAIL != (ret = PACKET_READ_ALLOCA(row_packet, conn)) && !row_packet.eof) {
int i;
unsigned int i;
zval **current_row;
if (!free_rows) {
@ -849,7 +993,7 @@ mysqlnd_store_result_fetch_data(MYSQLND * const conn, MYSQLND_RES *result,
/* {{{ mysqlnd_res::store_result */
MYSQLND_RES *
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
MYSQLND * const conn,
zend_bool ps_protocol TSRMLS_DC)
@ -959,7 +1103,7 @@ MYSQLND_METHOD(mysqlnd_res, data_seek)(MYSQLND_RES *result, uint64 row TSRMLS_DC
/* {{{ mysqlnd_res::num_fields */
uint64
static uint64
MYSQLND_METHOD(mysqlnd_res, num_rows)(const MYSQLND_RES * const res)
{
/* Be compatible with libmysql. We count row_count, but will return 0 */
@ -969,7 +1113,7 @@ MYSQLND_METHOD(mysqlnd_res, num_rows)(const MYSQLND_RES * const res)
/* {{{ mysqlnd_res::num_fields */
unsigned int
static unsigned int
MYSQLND_METHOD(mysqlnd_res, num_fields)(const MYSQLND_RES * const res)
{
return res->field_count;
@ -1066,6 +1210,27 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES *result, unsigned int flags,
/* }}} */
/* {{{ mysqlnd_res::fetch_row_c */
static MYSQLND_ROW_C
MYSQLND_METHOD(mysqlnd_res, fetch_row_c)(MYSQLND_RES *result TSRMLS_DC)
{
MYSQLND_ROW_C ret = NULL;
DBG_ENTER("mysqlnd_res::fetch_row_c");
if (result->m.fetch_row) {
if (result->m.fetch_row == result->m.fetch_row_normal_buffered) {
return mysqlnd_fetch_row_buffered_c(result TSRMLS_CC);
} else if (result->m.fetch_row == result->m.fetch_row_normal_unbuffered) {
return mysqlnd_fetch_row_unbuffered_c(result TSRMLS_CC);
} else {
*((int*)NULL) = 1;
}
}
DBG_RETURN(ret);
}
/* }}} */
/* {{{ mysqlnd_res::fetch_all */
static void
MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES *result, unsigned int flags,
@ -1108,7 +1273,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field_data)(MYSQLND_RES *result, unsigned int
{
zval row;
zval **entry;
uint i = 0;
unsigned int i = 0;
DBG_ENTER("mysqlnd_res::fetch_field_data");
DBG_INF_FMT("offset=%u", offset);
@ -1164,6 +1329,7 @@ MYSQLND_RES *mysqlnd_result_init(unsigned int field_count, MYSQLND_THD_ZVAL_PCAC
ret->m.num_rows = MYSQLND_METHOD(mysqlnd_res, num_rows);
ret->m.num_fields = MYSQLND_METHOD(mysqlnd_res, num_fields);
ret->m.fetch_into = MYSQLND_METHOD(mysqlnd_res, fetch_into);
ret->m.fetch_row_c = MYSQLND_METHOD(mysqlnd_res, fetch_row_c);
ret->m.fetch_all = MYSQLND_METHOD(mysqlnd_res, fetch_all);
ret->m.fetch_field_data = MYSQLND_METHOD(mysqlnd_res, fetch_field_data);
ret->m.seek_field = MYSQLND_METHOD(mysqlnd_res, field_seek);

View File

@ -141,7 +141,7 @@ static enum_func_status
MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta,
MYSQLND *conn TSRMLS_DC)
{
int i = 0;
unsigned int i = 0;
php_mysql_packet_res_field field_packet;
DBG_ENTER("mysqlnd_res_meta::read_metadata");

View File

@ -152,7 +152,7 @@ typedef struct st_mysqlnd_option
typedef struct st_mysqlnd_connection MYSQLND;
typedef struct st_mysqlnd_res MYSQLND_RES;
typedef char** MYSQLND_ROW; /* return data as array of strings */
typedef char** MYSQLND_ROW_C; /* return data as array of strings */
typedef struct st_mysqlnd_stmt MYSQLND_STMT;
typedef unsigned int MYSQLND_FIELD_OFFSET;
@ -200,7 +200,7 @@ typedef struct st_mysqlnd_net
struct st_mysqlnd_conn_methods
{
ulong (*escape_string)(const MYSQLND * const conn, char *newstr, const char *escapestr, int escapestr_len TSRMLS_DC);
ulong (*escape_string)(const MYSQLND * const conn, char *newstr, const char *escapestr, size_t escapestr_len TSRMLS_DC);
enum_func_status (*set_charset)(MYSQLND * const conn, const char * const charset TSRMLS_DC);
enum_func_status (*query)(MYSQLND *conn, const char *query, unsigned int query_len TSRMLS_DC);
MYSQLND_RES * (*use_result)(MYSQLND * const conn TSRMLS_DC);
@ -261,6 +261,7 @@ struct st_mysqlnd_res_methods
MYSQLND_RES * (*use_result)(MYSQLND_RES * const result, zend_bool ps_protocol TSRMLS_DC);
MYSQLND_RES * (*store_result)(MYSQLND_RES * result, MYSQLND * const conn, zend_bool ps TSRMLS_DC);
void (*fetch_into)(MYSQLND_RES *result, unsigned int flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC);
MYSQLND_ROW_C (*fetch_row_c)(MYSQLND_RES *result TSRMLS_DC);
void (*fetch_all)(MYSQLND_RES *result, unsigned int flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC);
void (*fetch_field_data)(MYSQLND_RES *result, unsigned int offset, zval *return_value TSRMLS_DC);
uint64 (*num_rows)(const MYSQLND_RES * const result);
@ -308,6 +309,7 @@ struct st_mysqlnd_stmt_methods
enum_func_status (*fetch)(MYSQLND_STMT * const stmt, zend_bool * const fetched_anything TSRMLS_DC);
enum_func_status (*bind_param)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * const param_bind TSRMLS_DC);
enum_func_status (*refresh_bind_param)(MYSQLND_STMT * const stmt TSRMLS_DC);
enum_func_status (*bind_result)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * const result_bind TSRMLS_DC);
enum_func_status (*send_long_data)(MYSQLND_STMT * const stmt, unsigned int param_num,
const char * const data, unsigned long length TSRMLS_DC);

View File

@ -480,7 +480,7 @@ size_t mysqlnd_read_body(MYSQLND *conn, zend_uchar *buf, size_t size TSRMLS_DC)
{
size_t ret;
char *p = (char *)buf;
int iter = 0;
unsigned int iter = 0;
MYSQLND_NET *net = &conn->net;
size_t old_chunk_size = net->stream->chunk_size;
@ -502,7 +502,7 @@ size_t mysqlnd_read_body(MYSQLND *conn, zend_uchar *buf, size_t size TSRMLS_DC)
#ifdef MYSQLND_DUMP_HEADER_N_BODY_FULL
{
int i;
unsigned int i;
DBG_INF_FMT("BODY: requested=%d last_read=%3d", p - (char*)buf, ret);
for (i = 0 ; i < p - (char*)buf; i++) {
if (i && (i % 30 == 0)) {
@ -746,7 +746,7 @@ php_mysqlnd_ok_read(void *_packet, MYSQLND *conn TSRMLS_DC)
zend_uchar buf[1024];
zend_uchar *p = buf;
zend_uchar *begin = buf;
int i;
unsigned long i;
register php_mysql_packet_ok *packet= (php_mysql_packet_ok *) _packet;
DBG_ENTER("php_mysqlnd_ok_read");
@ -1068,7 +1068,8 @@ php_mysqlnd_rset_field_read(void *_packet, MYSQLND *conn TSRMLS_DC)
zend_uchar *p = buf;
zend_uchar *begin = buf;
char *root_ptr;
size_t buf_len = conn->net.cmd_buffer.length, len, total_len = 0;
size_t buf_len = conn->net.cmd_buffer.length, total_len = 0;
unsigned long len;
MYSQLND_FIELD *meta;
unsigned int i, field_count = sizeof(rset_field_offsets)/sizeof(size_t);
@ -1309,7 +1310,7 @@ static
void php_mysqlnd_rowp_read_binary_protocol(php_mysql_packet_row *packet, MYSQLND *conn,
zend_uchar *p, size_t data_size TSRMLS_DC)
{
int i;
unsigned int i;
zend_uchar *null_ptr, bit;
zval **current_field, **end_field, **start_field;
zend_bool as_unicode = conn->options.numeric_and_datetime_as_unicode;
@ -1348,7 +1349,7 @@ void php_mysqlnd_rowp_read_binary_protocol(php_mysql_packet_row *packet, MYSQLND
0, &p, as_unicode TSRMLS_CC);
}
if (!((bit<<=1) & 255)) {
bit= 1; /* To next byte */
bit = 1; /* to the following byte */
null_ptr++;
}
}
@ -1365,7 +1366,7 @@ static
void php_mysqlnd_rowp_read_text_protocol(php_mysql_packet_row *packet, MYSQLND *conn,
zend_uchar *p, size_t data_size TSRMLS_DC)
{
int i;
unsigned int i;
zend_bool last_field_was_string;
zval **current_field, **end_field, **start_field;
zend_uchar *bit_area = packet->row_buffer + data_size + 1; /* we allocate from here */

View File

@ -157,13 +157,13 @@ typedef struct st_php_mysql_packet_auth {
uint32 max_packet_size;
mysqlnd_1b charset_no;
/* 23 byte pad */
char *user;
const char *user;
/* 8 byte scramble */
char *db;
const char *db;
/* 12 byte scramble */
/* Here the packet ends. This is user supplied data */
char *password;
const char *password;
/* +1 for \0 because of scramble() */
unsigned char *server_scramble_buf;
size_t db_len;