mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 21:42:35 +01:00
Merge bk-internal:/home/bk/mysql-4.1/
into serg.mylan:/usr/home/serg/Abk/mysql-4.1
This commit is contained in:
commit
0479213c10
6 changed files with 860 additions and 560 deletions
|
@ -87,8 +87,8 @@ typedef struct st_mysql_field {
|
|||
char *db; /* Database for table */
|
||||
char *catalog; /* Catalog for table */
|
||||
char *def; /* Default value (set by mysql_list_fields) */
|
||||
unsigned long length; /* Width of column */
|
||||
unsigned long max_length; /* Max width of selected set */
|
||||
unsigned long length; /* Width of column (create length) */
|
||||
unsigned long max_length; /* Max width for selected set */
|
||||
unsigned int name_length;
|
||||
unsigned int org_name_length;
|
||||
unsigned int table_length;
|
||||
|
@ -120,6 +120,7 @@ typedef unsigned long long my_ulonglong;
|
|||
typedef struct st_mysql_rows {
|
||||
struct st_mysql_rows *next; /* list of rows */
|
||||
MYSQL_ROW data;
|
||||
ulong length;
|
||||
} MYSQL_ROWS;
|
||||
|
||||
typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
|
||||
|
@ -547,11 +548,14 @@ typedef struct st_mysql_bind
|
|||
unsigned long offset; /* offset position for char/binary fetch */
|
||||
unsigned long internal_length; /* Used if length is 0 */
|
||||
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 long_data_used; /* If used with mysql_send_long_data */
|
||||
my_bool internal_is_null; /* Used if is_null is 0 */
|
||||
void (*store_param_func)(NET *net, struct st_mysql_bind *param);
|
||||
void (*fetch_result)(struct st_mysql_bind *, unsigned char **row);
|
||||
void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
|
||||
unsigned char **row);
|
||||
} MYSQL_BIND;
|
||||
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ my_bool net_flush(NET *net);
|
|||
#define MAX_LONG_DATA_LENGTH 8192
|
||||
#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);
|
||||
sig_handler pipe_sig_handler(int sig);
|
||||
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,
|
|||
{
|
||||
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:
|
||||
|
@ -2549,7 +2546,7 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
|
|||
switch (attr_type) {
|
||||
case STMT_ATTR_UPDATE_MAX_LENGTH:
|
||||
*(unsigned long *) value= stmt->update_max_length;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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)
|
||||
{
|
||||
MYSQL_BIND *param, *end;
|
||||
MYSQL_FIELD *field;
|
||||
ulong bind_count;
|
||||
uint param_count= 0;
|
||||
DBUG_ENTER("mysql_stmt_bind_result");
|
||||
|
@ -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);
|
||||
|
||||
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.
|
||||
|
@ -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 */
|
||||
switch (param->buffer_type) {
|
||||
case MYSQL_TYPE_NULL: /* for dummy binds */
|
||||
*param->length= 0;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY:
|
||||
param->fetch_result= fetch_result_tinyint;
|
||||
*param->length= 1;
|
||||
break;
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_YEAR:
|
||||
param->fetch_result= fetch_result_short;
|
||||
*param->length= 2;
|
||||
break;
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG:
|
||||
param->fetch_result= fetch_result_int32;
|
||||
*param->length= 4;
|
||||
|
@ -3445,6 +3485,58 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
|
|||
param->buffer_type, param_count);
|
||||
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;
|
||||
DBUG_RETURN(0);
|
||||
|
@ -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)
|
||||
{
|
||||
MYSQL_BIND *bind, *end;
|
||||
MYSQL_FIELD *field, *field_end;
|
||||
MYSQL_FIELD *field;
|
||||
uchar *null_ptr, bit;
|
||||
/*
|
||||
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)
|
|||
bit= 4; /* first 2 bits are reserved */
|
||||
|
||||
/* Copy complete row to application buffers */
|
||||
for (bind= stmt->bind, end= (MYSQL_BIND *) bind + stmt->field_count,
|
||||
field= stmt->fields,
|
||||
field_end= (MYSQL_FIELD *)stmt->fields+stmt->field_count;
|
||||
bind < end && field < field_end;
|
||||
for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields ;
|
||||
bind < end ;
|
||||
bind++, field++)
|
||||
{
|
||||
if (*null_ptr & bit)
|
||||
|
@ -3514,6 +3604,7 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cli_unbuffered_fetch(MYSQL *mysql, char **row)
|
||||
{
|
||||
if (packet_error == net_safe_read(mysql))
|
||||
|
@ -3524,6 +3615,7 @@ int cli_unbuffered_fetch(MYSQL *mysql, char **row)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Fetch and return row data to bound buffers, if any
|
||||
*/
|
||||
|
@ -3620,6 +3712,28 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
|
|||
|
||||
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)
|
||||
{
|
||||
cp= net->read_pos;
|
||||
|
@ -3629,13 +3743,16 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
|
|||
sizeof(MYSQL_ROWS) + pkt_len - 1)))
|
||||
{
|
||||
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
goto err;
|
||||
}
|
||||
cur->data= (MYSQL_ROW) (cur+1);
|
||||
*prev_ptr= cur;
|
||||
prev_ptr= &cur->next;
|
||||
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
|
||||
{
|
||||
|
@ -3647,6 +3764,8 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
|
|||
}
|
||||
}
|
||||
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||
|
||||
err:
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
@ -3909,6 +4028,49 @@ const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt)
|
|||
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
|
||||
*********************************************************************/
|
||||
|
|
|
@ -45,6 +45,7 @@ use strict;
|
|||
use Getopt::Long;
|
||||
|
||||
my $insert_portion_size= 15;
|
||||
my $maximum_line_length= 2040;
|
||||
my $error_prefix= "---- help parsing errors :";
|
||||
|
||||
my $path_to_lex_file= "../sql/lex.h";
|
||||
|
@ -166,6 +167,7 @@ sub add_description
|
|||
print_error "double description for $topic_name\n";
|
||||
}
|
||||
$topics{$topic_name}->{description}= $description;
|
||||
$topics{$topic_name}->{line_of_description}= $cur_line;
|
||||
add_topic_to_category($topic_name);
|
||||
}
|
||||
|
||||
|
@ -515,21 +517,52 @@ if (scalar(@topic_names))
|
|||
{
|
||||
my $header= "insert into help_topic ".
|
||||
"(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 $count= 0;
|
||||
foreach $topic_name (@topic_names)
|
||||
{
|
||||
print_insert_header($count,$header);
|
||||
my $topic= $topics{$topic_name};
|
||||
print "($count,";
|
||||
print "$topic->{category}->{__id__},";
|
||||
print "\"$topic_name\",";
|
||||
print "\"$topic->{description}\",";
|
||||
print "\"$topic->{example}\")";
|
||||
my $line= "($count,";
|
||||
$line.= "$topic->{category}->{__id__},";
|
||||
$line.= "\"$topic_name\",";
|
||||
$line.= "\"$topic->{description}\",";
|
||||
$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;
|
||||
$count++;
|
||||
}
|
||||
printf ";\n\n";
|
||||
if ($lines_in_accumulator ne 0)
|
||||
{
|
||||
print "$line_accumulator;\n";
|
||||
}
|
||||
printf "\n";
|
||||
}
|
||||
|
||||
my @keywords_names= keys(%keywords);
|
||||
|
|
|
@ -200,15 +200,28 @@ if test "$in_rpm" -eq 0 -a "$windows" -eq 0
|
|||
then
|
||||
echo "Installing all prepared tables"
|
||||
fi
|
||||
if (
|
||||
$scriptdir/mysql_create_system_tables $create_option $mdata $hostname $windows
|
||||
if test -n "$fill_help_tables"
|
||||
then
|
||||
cat $fill_help_tables
|
||||
fi
|
||||
) | eval "$mysqld $defaults $mysqld_opt --bootstrap --skip-grant-tables \
|
||||
--basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $args"
|
||||
mysqld_install_cmd_line="$mysqld $defaults $mysqld_opt --bootstrap \
|
||||
--skip-grant-tables --basedir=$basedir --datadir=$ldata --skip-innodb \
|
||||
--skip-bdb $args"
|
||||
if $scriptdir/mysql_create_system_tables $create_option $mdata $hostname $windows \
|
||||
| eval "$mysqld_install_cmd_line"
|
||||
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
|
||||
then
|
||||
echo ""
|
||||
|
@ -250,7 +263,7 @@ then
|
|||
fi
|
||||
exit 0
|
||||
else
|
||||
echo "Installation of grant tables failed!"
|
||||
echo "Installation of system tables failed!"
|
||||
echo
|
||||
echo "Examine the logs in $ldata for more information."
|
||||
echo "You can also try to start the mysqld daemon with:"
|
||||
|
|
|
@ -1095,6 +1095,12 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
|
|||
while (fgets(buff, thd->net.max_packet, file))
|
||||
{
|
||||
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]) ||
|
||||
buff[length-1] == ';'))
|
||||
length--;
|
||||
|
|
1140
tests/client_test.c
1140
tests/client_test.c
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue