summaryrefslogtreecommitdiff
path: root/libmysql
diff options
context:
space:
mode:
Diffstat (limited to 'libmysql')
-rw-r--r--libmysql/libmysql.c109
-rw-r--r--libmysql/libmysql.def2
2 files changed, 82 insertions, 29 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 455e5cc4118..bbff4e7a8d8 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2132,17 +2132,6 @@ mysql_stmt_param_metadata(MYSQL_STMT *stmt)
Prepare-execute, and param handling
*********************************************************************/
-/*
- Store the buffer type
-*/
-
-static void store_param_type(NET *net, uint type)
-{
- int2store(net->write_pos, type);
- net->write_pos+=2;
-}
-
-
/****************************************************************************
Functions to store parameter data from a prepared statement.
@@ -2390,7 +2379,11 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
that is sent to the server.
*/
for (param= stmt->params; param < param_end ; param++)
- store_param_type(net, (uint) param->buffer_type);
+ {
+ uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
+ int2store(net->write_pos, typecode);
+ net->write_pos+= 2;
+ }
}
for (param= stmt->params; param < param_end; param++)
@@ -2515,6 +2508,56 @@ stmt_read_row_no_data(MYSQL_STMT *stmt __attribute__((unused)),
return MYSQL_NO_DATA;
}
+
+/*
+ Get/set statement attributes
+
+ SYNOPSIS
+ mysql_stmt_attr_get()
+ mysql_stmt_attr_set()
+
+ attr_type statemenet attribute
+ value casted to const void * pointer to value.
+
+ RETURN VALUE
+ 0 success
+ !0 wrong attribute type
+*/
+
+my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
+ enum enum_stmt_attr_type attr_type,
+ const void *value)
+{
+ switch (attr_type) {
+ case STMT_ATTR_UPDATE_MAX_LENGTH:
+ /*
+ Do we need a flags variable for all attributes or a bool for each
+ attribute?
+ */
+ stmt->update_max_length= value ? *(const my_bool*) value : 0;
+ break;
+ default:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
+ enum enum_stmt_attr_type attr_type,
+ void *value)
+{
+ switch (attr_type) {
+ case STMT_ATTR_UPDATE_MAX_LENGTH:
+ *(unsigned long *) value= stmt->update_max_length;
+ break;
+ default:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
/*
Execute the prepared query
*/
@@ -3218,28 +3261,28 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row)
{
- *param->buffer= (uchar) **row;
+ *param->buffer= **row;
(*row)++;
}
static void fetch_result_short(MYSQL_BIND *param, uchar **row)
{
short value = (short)sint2korr(*row);
- int2store(param->buffer, value);
+ shortstore(param->buffer, value);
*row+= 2;
}
static void fetch_result_int32(MYSQL_BIND *param, uchar **row)
{
int32 value= (int32)sint4korr(*row);
- int4store(param->buffer, value);
+ longstore(param->buffer, value);
*row+= 4;
}
static void fetch_result_int64(MYSQL_BIND *param, uchar **row)
{
longlong value= (longlong)sint8korr(*row);
- int8store(param->buffer, value);
+ longlongstore(param->buffer, value);
*row+= 8;
}
@@ -3247,7 +3290,7 @@ static void fetch_result_float(MYSQL_BIND *param, uchar **row)
{
float value;
float4get(value,*row);
- float4store(param->buffer, value);
+ floatstore(param->buffer, value);
*row+= 4;
}
@@ -3255,7 +3298,7 @@ static void fetch_result_double(MYSQL_BIND *param, uchar **row)
{
double value;
float8get(value,*row);
- float8store(param->buffer, value);
+ doublestore(param->buffer, value);
*row+= 8;
}
@@ -3364,8 +3407,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
stmt->bind was initialized in mysql_stmt_prepare
*/
- memcpy((char*) stmt->bind, (char*) bind,
- sizeof(MYSQL_BIND)*bind_count);
+ memcpy((char*) stmt->bind, (char*) bind, sizeof(MYSQL_BIND) * bind_count);
for (param= stmt->bind, end= param + bind_count, field= stmt->fields ;
param < end ;
@@ -3537,10 +3579,20 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
bind++, field++)
{
if (*null_ptr & bit)
- *bind->is_null= bind->null_field= 1;
+ {
+ /*
+ We should set both inter_buffer and is_null to be able to see
+ nulls in mysql_stmt_fetch_column. This is because is_null may point
+ to user data which can be overwritten between mysql_stmt_fetch and
+ mysql_stmt_fetch_column, and in this case nullness of column will be
+ lost. See mysql_stmt_fetch_column for details.
+ */
+ bind->inter_buffer= NULL;
+ *bind->is_null= 1;
+ }
else
{
- *bind->is_null= bind->null_field= 0;
+ *bind->is_null= 0;
bind->inter_buffer= row;
if (field->type == bind->buffer_type)
(*bind->fetch_result)(bind, &row);
@@ -3626,14 +3678,8 @@ int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
DBUG_RETURN(1);
}
-
- if (param->null_field)
+ if (param->inter_buffer)
{
- if (bind->is_null)
- *bind->is_null= 1;
- }
- else
- {
MYSQL_FIELD *field= stmt->fields+column;
uchar *row= param->inter_buffer;
bind->offset= offset;
@@ -3645,6 +3691,11 @@ int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
bind->length= &param->internal_length; /* Needed for fetch_result() */
fetch_results(bind, field, &row);
}
+ else
+ {
+ if (bind->is_null)
+ *bind->is_null= 1;
+ }
DBUG_RETURN(0);
}
diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def
index 4f6347776e0..1790b0fa888 100644
--- a/libmysql/libmysql.def
+++ b/libmysql/libmysql.def
@@ -127,3 +127,5 @@ EXPORTS
mysql_stmt_prepare
mysql_stmt_init
mysql_stmt_insert_id
+ mysql_stmt_attr_get
+ mysql_stmt_attr_set