diff options
author | unknown <monty@mashka.mysql.fi> | 2003-09-11 19:06:23 +0300 |
---|---|---|
committer | unknown <monty@mashka.mysql.fi> | 2003-09-11 19:06:23 +0300 |
commit | dd0d199ebeab47facb4d01269cda97c258491c22 (patch) | |
tree | ba442d57a65bd55a0d0fec02aa6abeae237a568b /libmysql | |
parent | c9d1bdfac3956f5b32e338e620bd5698439bb43c (diff) | |
download | mariadb-git-dd0d199ebeab47facb4d01269cda97c258491c22.tar.gz |
After merge fixes.
Note that mix_innodb_myisam_binlog and union fails after this patch (Will be fixed shortly by maintaners of this code)
client/mysql.cc:
After merge fix
include/mysql.h:
Some additions to MYSQL_BIND for cleaner prepared statement code
libmysql/libmysql.c:
mysql_prepare_result -> mysql_get_metadata()
Added test for offset overflow when using mysql_fetch_column()
Cleaned up mysql_fetch_column()
Optimized fetch_result() usage
mysql-test/r/func_group.result:
Updated results after merge
mysql-test/r/func_test.result:
Updated results after merge
mysql-test/r/grant.result:
Updated results after merge
mysql-test/r/loaddata.result:
Updated results after merge
mysql-test/r/lowercase_table.result:
Updated results after merge
mysql-test/r/mix_innodb_myisam_binlog.result:
Updated results after merge (note that this is still not correct; Need patch to mysqld to fix this properly)
mysql-test/r/myisam.result:
Updated results after merge
mysql-test/r/range.result:
Updated results after merge
mysql-test/r/rpl_loaddata.result:
Updated results after merge
mysql-test/r/rpl_loaddata_rule_m.result:
Updated results after merge
mysql-test/r/rpl_loaddata_rule_s.result:
Updated results after merge
mysql-test/r/rpl_log.result:
Updated results after merge
mysql-test/r/union.result:
Updated results after merge
mysql-test/t/lowercase_table.test:
Update after merge
mysql-test/t/myisam.test:
Update after merge
mysql-test/t/union.test:
Update after merge
sql-bench/compare-results.sh:
Fix for now output format
sql/field.h:
Added is_null_in_record() to make ha_innodb.cc code more general
sql/ha_innodb.cc:
Removed some functions that uses inernal (private) MySQL information
sql/item_cmpfunc.cc:
After merge fix
sql/log_event.cc:
After merge fix; (Some code should be checked by Guilhem)
sql/opt_range.cc:
Simple optimzation and after merge fixes
sql/slave.cc:
After merge fix
sql/sql_acl.cc:
After merge fix + code cleanup
sql/sql_select.cc:
After merge fix
sql/sql_show.cc:
After merge fix
sql/sql_table.cc:
After merge fix
Cleanup of mysql_checksum_table()
sql/sql_union.cc:
After merge fixes.
Note that after this the union test still fails; Will be fixed shortly...
tests/client_test.c:
mysql_prepare_result() -> mysql_get_metadata()
Diffstat (limited to 'libmysql')
-rw-r--r-- | libmysql/libmysql.c | 171 |
1 files changed, 54 insertions, 117 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index cc45985a88c..afb785cf9d5 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1715,10 +1715,10 @@ unsigned int alloc_stmt_fields(MYSQL_STMT *stmt) */ MYSQL_RES * STDCALL -mysql_prepare_result(MYSQL_STMT *stmt) +mysql_get_metadata(MYSQL_STMT *stmt) { MYSQL_RES *result; - DBUG_ENTER("mysql_prepare_result"); + DBUG_ENTER("mysql_get_metadata"); if (!stmt->field_count || !stmt->fields) { @@ -1758,7 +1758,6 @@ mysql_param_result(MYSQL_STMT *stmt) } - /******************************************************************** Prepare-execute, and param handling *********************************************************************/ @@ -1773,6 +1772,7 @@ static void store_param_type(NET *net, uint type) net->write_pos+=2; } + /**************************************************************************** Functions to store parameter data from a prepared statement. @@ -1788,7 +1788,6 @@ static void store_param_type(NET *net, uint type) 1 Error (Can't alloc net->buffer) ****************************************************************************/ - static void store_param_tinyint(NET *net, MYSQL_BIND *param) { *(net->write_pos++)= (uchar) *param->buffer; @@ -2085,8 +2084,6 @@ my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt) static my_bool int_is_null_true= 1; /* Used for MYSQL_TYPE_NULL */ static my_bool int_is_null_false= 0; -static my_bool int_is_null_dummy; -static unsigned long param_length_is_dummy; /* Setup the parameter data buffers from application @@ -2422,7 +2419,10 @@ static void send_data_long(MYSQL_BIND *param, longlong value) char tmp[22]; /* Enough for longlong */ uint length= (uint)(longlong10_to_str(value,(char *)tmp,10)-tmp); ulong copy_length= min((ulong)length-param->offset, param->buffer_length); - memcpy(buffer, (char *)tmp+param->offset, copy_length); + if ((long) copy_length < 0) + copy_length=0; + else + memcpy(buffer, (char *)tmp+param->offset, copy_length); *param->length= length; if (copy_length != param->buffer_length) @@ -2470,7 +2470,10 @@ static void send_data_double(MYSQL_BIND *param, double value) char tmp[128]; uint length= my_sprintf(tmp,(tmp,"%g",value)); ulong copy_length= min((ulong)length-param->offset, param->buffer_length); - memcpy(buffer, (char *)tmp+param->offset, copy_length); + if ((long) copy_length < 0) + copy_length=0; + else + memcpy(buffer, (char *)tmp+param->offset, copy_length); *param->length= length; if (copy_length != param->buffer_length) @@ -2535,15 +2538,19 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length) case MYSQL_TYPE_BLOB: *param->length= length; length= min(length-param->offset, param->buffer_length); - memcpy(buffer, value+param->offset, length); + if ((long) length > 0) + memcpy(buffer, value+param->offset, length); break; default: *param->length= length; length= min(length-param->offset, param->buffer_length); - memcpy(buffer, value+param->offset, length); + if ((long) length < 0) + length= 0; + else + memcpy(buffer, value+param->offset, length); if (length != param->buffer_length) buffer[length]= '\0'; - } + } } @@ -2605,15 +2612,16 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime, /* Fetch data to buffers */ -static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row, - my_bool field_is_unsigned) +static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row) { ulong length; - + enum enum_field_types field_type= field->type; + switch (field_type) { case MYSQL_TYPE_TINY: { char value= (char) **row; + uint field_is_unsigned= (field->flags & UNSIGNED_FLAG); longlong data= ((field_is_unsigned) ? (longlong) (unsigned char) value: (longlong) value); send_data_long(param,data); @@ -2624,6 +2632,7 @@ static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row, case MYSQL_TYPE_YEAR: { short value= sint2korr(*row); + uint field_is_unsigned= (field->flags & UNSIGNED_FLAG); longlong data= ((field_is_unsigned) ? (longlong) (unsigned short) value: (longlong) value); send_data_long(param,data); @@ -2633,6 +2642,7 @@ static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row, case MYSQL_TYPE_LONG: { long value= sint4korr(*row); + uint field_is_unsigned= (field->flags & UNSIGNED_FLAG); longlong data= ((field_is_unsigned) ? (longlong) (unsigned long) value: (longlong) value); send_data_long(param,data); @@ -2781,24 +2791,6 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row) *row+= length; } -static uint default_binary_field_length(uint field_type) -{ - switch(field_type) { - case MYSQL_TYPE_TINY: - return 1; - case MYSQL_TYPE_SHORT: - return 2; - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_FLOAT: - return 4; - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_DOUBLE: - return 8; - default: - return 0; - } -} - /* Setup the bind buffers for resultset processing @@ -2838,10 +2830,10 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) This is to make the excute code easier */ if (!param->is_null) - param->is_null= &int_is_null_dummy; + param->is_null= ¶m->internal_is_null; if (!param->length) - param->length= ¶m_length_is_dummy; + param->length= ¶m->internal_length; param->param_number= param_count++; param->offset= 0; @@ -2945,10 +2937,7 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) if (field->type == bind->buffer_type) (*bind->fetch_result)(bind, &row); else - { - my_bool field_is_unsigned= (field->flags & UNSIGNED_FLAG) ? 1: 0; - fetch_results(bind, field->type, &row, field_is_unsigned); - } + fetch_results(bind, field, &row); } if (!((bit<<=1) & 255)) { @@ -2970,8 +2959,8 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt) uchar *row; DBUG_ENTER("mysql_fetch"); - stmt->last_fetched_column= 0; /* reset */ - if (stmt->result_buffered) /* buffered */ + stmt->last_fetched_column= 0; /* reset */ + if (stmt->result_buffered) /* buffered */ { MYSQL_RES *res; @@ -2986,7 +2975,7 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt) row= (uchar *)res->data_cursor->data; res->data_cursor= res->data_cursor->next; } - else /* un-buffered */ + else /* un-buffered */ { if (packet_error == net_safe_read(mysql)) { @@ -3012,107 +3001,55 @@ no_data: /* - Fetch only specified column data to buffers + Fetch datat for one specified column data + + SYNOPSIS + mysql_fetch_column() + stmt Prepared statement handler + bind Where date should be placed. Should be filled in as + when calling mysql_bind_param() + column Column to fetch (first column is 0) + ulong offset Offset in result data (to fetch blob in pieces) + This is normally 0 + RETURN + 0 ok + 1 error */ int STDCALL mysql_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, - my_ulonglong icol, - ulong offset) + uint column, ulong offset) { - uchar *row; - my_bool null_data; - + MYSQL_BIND *param= stmt->bind+column; DBUG_ENTER("mysql_fetch_column"); - if (!(row= stmt->current_row)) + if (!stmt->current_row) goto no_data; #ifdef CHECK_EXTRA_ARGUMENTS - if (!bind || icol >= stmt->field_count) + if (column >= stmt->field_count) { - set_stmt_errmsg(stmt, "Invalid column descriptor or offset",1, - unknown_sqlstate); + set_stmt_errmsg(stmt, "Invalid column descriptor",1, unknown_sqlstate); DBUG_RETURN(1); } #endif - /* column '0' == first column */ - if (stmt->res_buffers) - { - /* - Already buffers are parsed and cached to stmt->bind - during mysql_fetch() call. - */ - MYSQL_BIND *param= stmt->bind+icol; - null_data= param->null_field; - row= param->inter_buffer; - } - else - { - if (stmt->last_fetched_column == icol+1) - { - /* - Data buffer is already parsed during the last call, get - the cached information - */ - if (!stmt->last_fetched_buffer) - null_data= 1; - else - { - null_data= 0; - row= stmt->last_fetched_buffer; - } - } - else - { - /* - Advance the data buffer to icol position and cache - the information for subsequent calls - */ - uint bit= icol > 6 ? 1 : 4; - stmt->last_fetched_column= icol+1; - - if (row[icol/8] & (bit << icol & 7)) - { - stmt->last_fetched_buffer= 0; - null_data= 1; - } - else - { - uint length, i; - - null_data= 0; - row+= (stmt->field_count+9)/8; /* skip null bits */ - - for (i=0; i < icol; i++) - { - if (!(length= default_binary_field_length((uint)(stmt->fields[i]. - type)))) - length= net_field_length(&row); - row+= length; - } - stmt->last_fetched_buffer= row; - } - } - } - if (null_data) + if (param->null_field) { if (bind->is_null) *bind->is_null= 1; } else { - MYSQL_FIELD *field= stmt->fields+icol; - my_bool field_is_unsigned= (field->flags & UNSIGNED_FLAG) ? 1: 0; - + MYSQL_FIELD *field= stmt->fields+column; + uchar *row= param->inter_buffer; bind->offset= offset; if (bind->is_null) *bind->is_null= 0; if (bind->length) /* Set the length if non char/binary types */ - *bind->length= default_binary_field_length(field->type); + *bind->length= *param->length; else - bind->length= ¶m_length_is_dummy; - fetch_results(bind, field->type, &row, field_is_unsigned); + bind->length= ¶m->internal_length; /* Needed for fetch_result() */ + fetch_results(bind, field, &row); } DBUG_RETURN(0); |