Commit 0479213c authored by serg@serg.mylan's avatar serg@serg.mylan

Merge bk-internal:/home/bk/mysql-4.1/

into serg.mylan:/usr/home/serg/Abk/mysql-4.1
parents 8128b7db 661aeb5a
...@@ -87,8 +87,8 @@ typedef struct st_mysql_field { ...@@ -87,8 +87,8 @@ typedef struct st_mysql_field {
char *db; /* Database for table */ char *db; /* Database for table */
char *catalog; /* Catalog for table */ char *catalog; /* Catalog for table */
char *def; /* Default value (set by mysql_list_fields) */ char *def; /* Default value (set by mysql_list_fields) */
unsigned long length; /* Width of column */ unsigned long length; /* Width of column (create length) */
unsigned long max_length; /* Max width of selected set */ unsigned long max_length; /* Max width for selected set */
unsigned int name_length; unsigned int name_length;
unsigned int org_name_length; unsigned int org_name_length;
unsigned int table_length; unsigned int table_length;
...@@ -120,6 +120,7 @@ typedef unsigned long long my_ulonglong; ...@@ -120,6 +120,7 @@ typedef unsigned long long my_ulonglong;
typedef struct st_mysql_rows { typedef struct st_mysql_rows {
struct st_mysql_rows *next; /* list of rows */ struct st_mysql_rows *next; /* list of rows */
MYSQL_ROW data; MYSQL_ROW data;
ulong length;
} MYSQL_ROWS; } MYSQL_ROWS;
typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
...@@ -547,11 +548,14 @@ typedef struct st_mysql_bind ...@@ -547,11 +548,14 @@ typedef struct st_mysql_bind
unsigned long offset; /* offset position for char/binary fetch */ unsigned long offset; /* offset position for char/binary fetch */
unsigned long internal_length; /* Used if length is 0 */ unsigned long internal_length; /* Used if length is 0 */
unsigned int param_number; /* For null count and error messages */ unsigned int param_number; /* For null count and error messages */
unsigned int pack_length; /* Internal length for packed data */
my_bool is_unsigned; /* set if integer type is unsigned */ my_bool is_unsigned; /* set if integer type is unsigned */
my_bool long_data_used; /* If used with mysql_send_long_data */ my_bool long_data_used; /* If used with mysql_send_long_data */
my_bool internal_is_null; /* Used if is_null is 0 */ my_bool internal_is_null; /* Used if is_null is 0 */
void (*store_param_func)(NET *net, struct st_mysql_bind *param); void (*store_param_func)(NET *net, struct st_mysql_bind *param);
void (*fetch_result)(struct st_mysql_bind *, unsigned char **row); void (*fetch_result)(struct st_mysql_bind *, unsigned char **row);
void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
unsigned char **row);
} MYSQL_BIND; } MYSQL_BIND;
......
...@@ -85,6 +85,7 @@ my_bool net_flush(NET *net); ...@@ -85,6 +85,7 @@ my_bool net_flush(NET *net);
#define MAX_LONG_DATA_LENGTH 8192 #define MAX_LONG_DATA_LENGTH 8192
#define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG) #define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG)
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data);
static void append_wild(char *to,char *end,const char *wild); static void append_wild(char *to,char *end,const char *wild);
sig_handler pipe_sig_handler(int sig); sig_handler pipe_sig_handler(int sig);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
...@@ -2529,10 +2530,6 @@ my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt, ...@@ -2529,10 +2530,6 @@ my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
{ {
switch (attr_type) { switch (attr_type) {
case STMT_ATTR_UPDATE_MAX_LENGTH: 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; stmt->update_max_length= value ? *(const my_bool*) value : 0;
break; break;
default: default:
...@@ -2549,7 +2546,7 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, ...@@ -2549,7 +2546,7 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
switch (attr_type) { switch (attr_type) {
case STMT_ATTR_UPDATE_MAX_LENGTH: case STMT_ATTR_UPDATE_MAX_LENGTH:
*(unsigned long *) value= stmt->update_max_length; *(unsigned long *) value= stmt->update_max_length;
break; break;
default: default:
return TRUE; return TRUE;
} }
...@@ -3341,6 +3338,43 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row) ...@@ -3341,6 +3338,43 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row)
} }
/*
functions to calculate max lengths for strings during
mysql_stmt_store_result()
*/
static void skip_result_fixed(MYSQL_BIND *param,
MYSQL_FIELD *field __attribute__((unused)),
uchar **row)
{
(*row)+= param->pack_length;
}
static void skip_result_with_length(MYSQL_BIND *param __attribute__((unused)),
MYSQL_FIELD *field __attribute__((unused)),
uchar **row)
{
ulong length= net_field_length(row);
(*row)+= length;
}
static void skip_result_string(MYSQL_BIND *param __attribute__((unused)),
MYSQL_FIELD *field,
uchar **row)
{
ulong length= net_field_length(row);
(*row)+= length;
if (field->max_length < length)
field->max_length= length;
}
/* /*
Setup the bind buffers for resultset processing Setup the bind buffers for resultset processing
*/ */
...@@ -3348,6 +3382,7 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row) ...@@ -3348,6 +3382,7 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row)
my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
{ {
MYSQL_BIND *param, *end; MYSQL_BIND *param, *end;
MYSQL_FIELD *field;
ulong bind_count; ulong bind_count;
uint param_count= 0; uint param_count= 0;
DBUG_ENTER("mysql_stmt_bind_result"); DBUG_ENTER("mysql_stmt_bind_result");
...@@ -3370,7 +3405,9 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) ...@@ -3370,7 +3405,9 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
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; param < end ; param++) for (param= stmt->bind, end= param + bind_count, field= stmt->fields ;
param < end ;
param++, field++)
{ {
/* /*
Set param->is_null to point to a dummy variable if it's not set. Set param->is_null to point to a dummy variable if it's not set.
...@@ -3388,15 +3425,18 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) ...@@ -3388,15 +3425,18 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
/* Setup data copy functions for the different supported types */ /* Setup data copy functions for the different supported types */
switch (param->buffer_type) { switch (param->buffer_type) {
case MYSQL_TYPE_NULL: /* for dummy binds */ case MYSQL_TYPE_NULL: /* for dummy binds */
*param->length= 0;
break; break;
case MYSQL_TYPE_TINY: case MYSQL_TYPE_TINY:
param->fetch_result= fetch_result_tinyint; param->fetch_result= fetch_result_tinyint;
*param->length= 1; *param->length= 1;
break; break;
case MYSQL_TYPE_SHORT: case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_YEAR:
param->fetch_result= fetch_result_short; param->fetch_result= fetch_result_short;
*param->length= 2; *param->length= 2;
break; break;
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONG:
param->fetch_result= fetch_result_int32; param->fetch_result= fetch_result_int32;
*param->length= 4; *param->length= 4;
...@@ -3445,6 +3485,58 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) ...@@ -3445,6 +3485,58 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
param->buffer_type, param_count); param->buffer_type, param_count);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* Setup skip_result functions (to calculate max_length) */
param->skip_result= skip_result_fixed;
switch (field->type) {
case MYSQL_TYPE_NULL: /* for dummy binds */
param->pack_length= 0;
break;
case MYSQL_TYPE_TINY:
param->pack_length= 1;
break;
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_SHORT:
param->pack_length= 2;
break;
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
param->pack_length= 4;
break;
case MYSQL_TYPE_LONGLONG:
param->pack_length= 8;
break;
case MYSQL_TYPE_FLOAT:
param->pack_length= 4;
break;
case MYSQL_TYPE_DOUBLE:
param->pack_length= 8;
break;
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
param->skip_result= skip_result_with_length;
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
param->skip_result= skip_result_string;
break;
default:
strmov(stmt->sqlstate, unknown_sqlstate);
sprintf(stmt->last_error,
ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
field->type, param_count);
DBUG_RETURN(1);
}
} }
stmt->bind_result_done= TRUE; stmt->bind_result_done= TRUE;
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -3458,7 +3550,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) ...@@ -3458,7 +3550,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
{ {
MYSQL_BIND *bind, *end; MYSQL_BIND *bind, *end;
MYSQL_FIELD *field, *field_end; MYSQL_FIELD *field;
uchar *null_ptr, bit; uchar *null_ptr, bit;
/* /*
Precondition: if stmt->field_count is zero or row is NULL, read_row_* Precondition: if stmt->field_count is zero or row is NULL, read_row_*
...@@ -3478,10 +3570,8 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) ...@@ -3478,10 +3570,8 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
bit= 4; /* first 2 bits are reserved */ bit= 4; /* first 2 bits are reserved */
/* Copy complete row to application buffers */ /* Copy complete row to application buffers */
for (bind= stmt->bind, end= (MYSQL_BIND *) bind + stmt->field_count, for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields ;
field= stmt->fields, bind < end ;
field_end= (MYSQL_FIELD *)stmt->fields+stmt->field_count;
bind < end && field < field_end;
bind++, field++) bind++, field++)
{ {
if (*null_ptr & bit) if (*null_ptr & bit)
...@@ -3514,6 +3604,7 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) ...@@ -3514,6 +3604,7 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
return 0; return 0;
} }
int cli_unbuffered_fetch(MYSQL *mysql, char **row) int cli_unbuffered_fetch(MYSQL *mysql, char **row)
{ {
if (packet_error == net_safe_read(mysql)) if (packet_error == net_safe_read(mysql))
...@@ -3524,6 +3615,7 @@ int cli_unbuffered_fetch(MYSQL *mysql, char **row) ...@@ -3524,6 +3615,7 @@ int cli_unbuffered_fetch(MYSQL *mysql, char **row)
return 0; return 0;
} }
/* /*
Fetch and return row data to bound buffers, if any Fetch and return row data to bound buffers, if any
*/ */
...@@ -3620,6 +3712,28 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) ...@@ -3620,6 +3712,28 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
mysql= mysql->last_used_con; mysql= mysql->last_used_con;
if (stmt->update_max_length && !stmt->bind_result_done)
{
/*
We must initalize the bind structure to be able to calculate
max_length
*/
MYSQL_BIND *bind, *end;
MYSQL_FIELD *field;
bzero((char*) stmt->bind, sizeof(*stmt->bind)* stmt->field_count);
for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields;
bind < end ;
bind++, field++)
{
bind->buffer_type= field->type;
bind->buffer_length=1;
}
mysql_stmt_bind_result(stmt, stmt->bind);
stmt->bind_result_done= 0; /* No normal bind done */
}
while ((pkt_len= net_safe_read(mysql)) != packet_error) while ((pkt_len= net_safe_read(mysql)) != packet_error)
{ {
cp= net->read_pos; cp= net->read_pos;
...@@ -3629,13 +3743,16 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) ...@@ -3629,13 +3743,16 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
sizeof(MYSQL_ROWS) + pkt_len - 1))) sizeof(MYSQL_ROWS) + pkt_len - 1)))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(1); goto err;
} }
cur->data= (MYSQL_ROW) (cur+1); cur->data= (MYSQL_ROW) (cur+1);
*prev_ptr= cur; *prev_ptr= cur;
prev_ptr= &cur->next; prev_ptr= &cur->next;
memcpy((char *) cur->data, (char *) cp+1, pkt_len-1); memcpy((char *) cur->data, (char *) cp+1, pkt_len-1);
++result->rows; cur->length= pkt_len; /* To allow us to do sanity checks */
result->rows++;
if (stmt->update_max_length)
stmt_update_metadata(stmt, cur);
} }
else else
{ {
...@@ -3647,6 +3764,8 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) ...@@ -3647,6 +3764,8 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
} }
} }
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
err:
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -3909,6 +4028,49 @@ const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt) ...@@ -3909,6 +4028,49 @@ const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt)
DBUG_RETURN(stmt->last_error); DBUG_RETURN(stmt->last_error);
} }
/*
Update meta data for statement
SYNOPSIS
stmt_update_metadata()
stmt Statement handler
row Binary data
NOTES
Only updates MYSQL_FIELD->max_length for strings
*/
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data)
{
MYSQL_BIND *bind, *end;
MYSQL_FIELD *field;
uchar *null_ptr, bit;
uchar *row= (uchar*) data->data;
uchar *row_end= row + data->length;
null_ptr= row;
row+= (stmt->field_count+9)/8; /* skip null bits */
bit= 4; /* first 2 bits are reserved */
/* Go throw all fields and calculate metadata */
for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields ;
bind < end ;
bind++, field++)
{
if (!(*null_ptr & bit))
(*bind->skip_result)(bind, field, &row);
DBUG_ASSERT(row <= row_end);
if (!((bit<<=1) & 255))
{
bit= 1; /* To next byte */
null_ptr++;
}
}
}
/******************************************************************** /********************************************************************
Transactional APIs Transactional APIs
*********************************************************************/ *********************************************************************/
......
...@@ -45,6 +45,7 @@ use strict; ...@@ -45,6 +45,7 @@ use strict;
use Getopt::Long; use Getopt::Long;
my $insert_portion_size= 15; my $insert_portion_size= 15;
my $maximum_line_length= 2040;
my $error_prefix= "---- help parsing errors :"; my $error_prefix= "---- help parsing errors :";
my $path_to_lex_file= "../sql/lex.h"; my $path_to_lex_file= "../sql/lex.h";
...@@ -166,6 +167,7 @@ sub add_description ...@@ -166,6 +167,7 @@ sub add_description
print_error "double description for $topic_name\n"; print_error "double description for $topic_name\n";
} }
$topics{$topic_name}->{description}= $description; $topics{$topic_name}->{description}= $description;
$topics{$topic_name}->{line_of_description}= $cur_line;
add_topic_to_category($topic_name); add_topic_to_category($topic_name);
} }
...@@ -515,21 +517,52 @@ if (scalar(@topic_names)) ...@@ -515,21 +517,52 @@ if (scalar(@topic_names))
{ {
my $header= "insert into help_topic ". my $header= "insert into help_topic ".
"(help_topic_id,help_category_id,name,description,example) values "; "(help_topic_id,help_category_id,name,description,example) values ";
my $line_accumulator= $header;
my $lines_in_accumulator= 0;
my $actual_max_line_length= $maximum_line_length-2; # for ";\n"
my $topic_name; my $topic_name;
my $count= 0; my $count= 0;
foreach $topic_name (@topic_names) foreach $topic_name (@topic_names)
{ {
print_insert_header($count,$header);
my $topic= $topics{$topic_name}; my $topic= $topics{$topic_name};
print "($count,"; my $line= "($count,";
print "$topic->{category}->{__id__},"; $line.= "$topic->{category}->{__id__},";
print "\"$topic_name\","; $line.= "\"$topic_name\",";
print "\"$topic->{description}\","; $line.= "\"$topic->{description}\",";
print "\"$topic->{example}\")"; $line.= "\"$topic->{example}\")";
if ($lines_in_accumulator <= $insert_portion_size &&
length($line) + length($line_accumulator) < $actual_max_line_length)
{
if ($lines_in_accumulator ne 0)
{
$line_accumulator.= ",";
}
$line_accumulator.= $line;
$lines_in_accumulator++;
}
else
{
if (length($line) + length($header) >= $actual_max_line_length)
{
$cur_line= $topics{$topic_name}->{line_of_description};
print_error "too long record for topic \"$topic_name\" \n".
" please decrease its description or example!\n";
}
else
{
print "$line_accumulator;\n";
$line_accumulator= $header.$line;
$lines_in_accumulator= 1;
}
}
$topics{$topic_name}->{__id__}= $count; $topics{$topic_name}->{__id__}= $count;
$count++; $count++;
} }
printf ";\n\n"; if ($lines_in_accumulator ne 0)
{
print "$line_accumulator;\n";
}
printf "\n";
} }
my @keywords_names= keys(%keywords); my @keywords_names= keys(%keywords);
......
...@@ -200,15 +200,28 @@ if test "$in_rpm" -eq 0 -a "$windows" -eq 0 ...@@ -200,15 +200,28 @@ if test "$in_rpm" -eq 0 -a "$windows" -eq 0
then then
echo "Installing all prepared tables" echo "Installing all prepared tables"
fi fi
if ( mysqld_install_cmd_line="$mysqld $defaults $mysqld_opt --bootstrap \
$scriptdir/mysql_create_system_tables $create_option $mdata $hostname $windows --skip-grant-tables --basedir=$basedir --datadir=$ldata --skip-innodb \
if test -n "$fill_help_tables" --skip-bdb $args"
then if $scriptdir/mysql_create_system_tables $create_option $mdata $hostname $windows \
cat $fill_help_tables | eval "$mysqld_install_cmd_line"
fi
) | eval "$mysqld $defaults $mysqld_opt --bootstrap --skip-grant-tables \
--basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $args"
then then
if test -n "$fill_help_tables"
then
if test "$in_rpm" -eq 0 -a "$windows" -eq 0
then
echo "Fill help tables"
fi
if ! (echo "use mysql;
"
cat $fill_help_tables) | eval "$mysqld_install_cmd_line"
then
echo ""
echo "WARNING: HELP FILES ARE NOT COMPLETELY INSTALLED!"
echo "The \"HELP\" command might not work properly"
echo ""
fi
fi
if test "$in_rpm" = 0 -a "$windows" = 0 if test "$in_rpm" = 0 -a "$windows" = 0
then then
echo "" echo ""
...@@ -250,7 +263,7 @@ then ...@@ -250,7 +263,7 @@ then
fi fi
exit 0 exit 0
else else
echo "Installation of grant tables failed!" echo "Installation of system tables failed!"
echo echo
echo "Examine the logs in $ldata for more information." echo "Examine the logs in $ldata for more information."
echo "You can also try to start the mysqld daemon with:" echo "You can also try to start the mysqld daemon with:"
......
...@@ -1095,6 +1095,12 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) ...@@ -1095,6 +1095,12 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
while (fgets(buff, thd->net.max_packet, file)) while (fgets(buff, thd->net.max_packet, file))
{ {
uint length=(uint) strlen(buff); uint length=(uint) strlen(buff);
if (buff[length-1]!='\n' && !feof(file))
{
send_error(thd,ER_NET_PACKET_TOO_LARGE, NullS);
thd->is_fatal_error= 1;
break;
}
while (length && (my_isspace(thd->charset(), buff[length-1]) || while (length && (my_isspace(thd->charset(), buff[length-1]) ||
buff[length-1] == ';')) buff[length-1] == ';'))
length--; length--;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment