Commit ddbef950 authored by unknown's avatar unknown

Merge neptunus.(none):/home/magnus/mysql-4.1

into neptunus.(none):/home/magnus/mysql-4.1-sql-bench


sql/ha_ndbcluster.cc:
  Auto merged
sql/ha_ndbcluster.h:
  Auto merged
parents 74a46d13 4960b897
...@@ -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
*********************************************************************/ *********************************************************************/
......
...@@ -22,9 +22,9 @@ done ...@@ -22,9 +22,9 @@ done
stop_default_ndbcluster() { stop_default_ndbcluster() {
if [ ! -f $pidfile ] ; then #if [ ! -f $pidfile ] ; then
exit 0 # exit 0
fi #fi
if [ ! -f $cfgfile ] ; then if [ ! -f $cfgfile ] ; then
echo "$cfgfile missing" echo "$cfgfile missing"
...@@ -43,8 +43,11 @@ echo "all stop" | $exec_mgmtclient ...@@ -43,8 +43,11 @@ echo "all stop" | $exec_mgmtclient
sleep 5 sleep 5
kill `cat $pidfile` if [ -f $pidfile ] ; then
rm $pidfile kill `cat $pidfile`
rm $pidfile
fi
} }
stop_default_ndbcluster stop_default_ndbcluster
......
...@@ -119,3 +119,72 @@ select * from t1 order by a; ...@@ -119,3 +119,72 @@ select * from t1 order by a;
a b c a b c
4 5 12 4 5 12
drop table t1; drop table t1;
CREATE TABLE t1 (
a int unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
c int unsigned not null,
) engine = ndb;
create index a1 on t1 (b, c);
insert into t1 values (1, 2, 13);
insert into t1 values (2,3, 13);
insert into t1 values (3, 4, 12);
insert into t1 values (4, 5, 12);
insert into t1 values (5,6, 12);
insert into t1 values (6,7, 12);
insert into t1 values (7, 2, 1);
insert into t1 values (8,3, 6);
insert into t1 values (9, 4, 12);
insert into t1 values (14, 5, 4);
insert into t1 values (15,5,5);
insert into t1 values (16,5, 6);
insert into t1 values (17,4,4);
insert into t1 values (18,1, 7);
select * from t1 order by a;
a b c
1 2 13
2 3 13
3 4 12
4 5 12
5 6 12
6 7 12
7 2 1
8 3 6
9 4 12
14 5 4
15 5 5
16 5 6
17 4 4
18 1 7
select * from t1 where b<=5 order by a;
a b c
1 2 13
2 3 13
3 4 12
4 5 12
7 2 1
8 3 6
9 4 12
14 5 4
15 5 5
16 5 6
17 4 4
18 1 7
select * from t1 where b<=5 and c=0;
a b c
insert into t1 values (19,4, 0);
select * from t1 where b<=5 and c=0;
a b c
19 4 0
select * from t1 where b=4 and c<=5;
a b c
19 4 0
17 4 4
select * from t1 where b<=4 and c<=5 order by a;
a b c
7 2 1
17 4 4
19 4 0
select * from t1 where b<=5 and c=0 or b<=5 and c=2;
a b c
19 4 0
drop table t1;
This diff is collapsed.
...@@ -32,7 +32,7 @@ select * from t1 where b <= 4 order by b; ...@@ -32,7 +32,7 @@ select * from t1 where b <= 4 order by b;
# Update using ordered index scan # Update using ordered index scan
# #
# MASV update t1 set c = 3 where b = 3; update t1 set c = 3 where b = 3;
select * from t1 order by a; select * from t1 order by a;
update t1 set c = 10 where b >= 6; update t1 set c = 10 where b >= 6;
select * from t1 order by a; select * from t1 order by a;
...@@ -59,7 +59,7 @@ CREATE TABLE t1 ( ...@@ -59,7 +59,7 @@ CREATE TABLE t1 (
insert t1 values(1, 2, 13), (2,3, 13), (3, 4, 12), (4, 5, 12), (5,6, 12), (6,7, 12); insert t1 values(1, 2, 13), (2,3, 13), (3, 4, 12), (4, 5, 12), (5,6, 12), (6,7, 12);
# MASV delete from t1 where b = 3; delete from t1 where b = 3;
select * from t1 order by a; select * from t1 order by a;
delete from t1 where b >= 6; delete from t1 where b >= 6;
select * from t1 order by a; select * from t1 order by a;
...@@ -97,11 +97,16 @@ insert into t1 values (14, 5, 4); ...@@ -97,11 +97,16 @@ insert into t1 values (14, 5, 4);
insert into t1 values (15,5,5); insert into t1 values (15,5,5);
insert into t1 values (16,5, 6); insert into t1 values (16,5, 6);
insert into t1 values (17,4,4); insert into t1 values (17,4,4);
insert into t1 values (18,1, 7);
select * from t1 order by a; select * from t1 order by a;
select * from t1 where b<=5; select * from t1 where b<=5 order by a;
#select * from t1 where b<=5 and c=0; select * from t1 where b<=5 and c=0;
#select * from t1 where b=4 and c<=5; insert into t1 values (19,4, 0);
select * from t1 where b<=4 and c<=5; select * from t1 where b<=5 and c=0;
# MASV select * from t1 where b<=5 and c=0 or b<=5 and c=2; select * from t1 where b=4 and c<=5;
select * from t1 where b<=4 and c<=5 order by a;
select * from t1 where b<=5 and c=0 or b<=5 and c=2;
drop table t1; drop table t1;
This diff is collapsed.
...@@ -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:"
......
...@@ -682,25 +682,80 @@ inline int ha_ndbcluster::next_result(byte *buf) ...@@ -682,25 +682,80 @@ inline int ha_ndbcluster::next_result(byte *buf)
} }
/*
Set bounds for a ordered index scan, use key_range
*/
int ha_ndbcluster::set_bounds(NdbOperation *op,
const key_range *key,
int bound)
{
uint i, tot_len;
byte *key_ptr;
KEY* key_info= table->key_info + active_index;
KEY_PART_INFO* key_part= key_info->key_part;
KEY_PART_INFO* end= key_part+key_info->key_parts;
DBUG_ENTER("set_bounds");
DBUG_PRINT("enter", ("bound: %d", bound));
DBUG_PRINT("enter", ("key_parts: %d", key_info->key_parts));
DBUG_PRINT("enter", ("key->length: %d", key->length));
DBUG_PRINT("enter", ("key->flag: %d", key->flag));
// Set bounds using key data
tot_len= 0;
key_ptr= (byte *) key->key;
for (; key_part != end; key_part++)
{
Field* field= key_part->field;
uint32 field_len= field->pack_length();
tot_len+= field_len;
const char* bounds[]= {"LE", "LT", "GE", "GT", "EQ"};
DBUG_ASSERT(bound >= 0 && bound <= 4);
DBUG_PRINT("info", ("Set Bound%s on %s",
bounds[bound],
field->field_name));
DBUG_DUMP("key", (char*)key_ptr, field_len);
if (op->setBound(field->field_name,
bound,
key_ptr,
field_len) != 0)
ERR_RETURN(op->getNdbError());
key_ptr+= field_len;
if (tot_len >= key->length)
break;
/*
Only one bound which is not EQ can be set
so if this bound was not EQ, bail out and make
a best effort attempt
*/
if (bound != NdbOperation::BoundEQ)
break;
}
DBUG_RETURN(0);
}
/* /*
Read record(s) from NDB using ordered index scan Read record(s) from NDB using ordered index scan
*/ */
int ha_ndbcluster::ordered_index_scan(const byte *key, uint key_len, int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
byte *buf, const key_range *end_key,
enum ha_rkey_function find_flag) bool sorted, byte* buf)
{ {
uint no_fields= table->fields; uint no_fields= table->fields;
uint tot_len, i; uint i;
NdbConnection *trans= m_active_trans; NdbConnection *trans= m_active_trans;
NdbResultSet *cursor= m_active_cursor; NdbResultSet *cursor= m_active_cursor;
NdbScanOperation *op; NdbScanOperation *op;
const char *bound_str= NULL;
const char *index_name; const char *index_name;
NdbOperation::BoundType bound_type = NdbOperation::BoundEQ;
bool can_be_handled_by_ndb= FALSE;
byte *key_ptr;
KEY *key_info;
THD* thd = current_thd; THD* thd = current_thd;
DBUG_ENTER("ordered_index_scan"); DBUG_ENTER("ordered_index_scan");
DBUG_PRINT("enter", ("index: %u", active_index)); DBUG_PRINT("enter", ("index: %u", active_index));
...@@ -712,77 +767,27 @@ int ha_ndbcluster::ordered_index_scan(const byte *key, uint key_len, ...@@ -712,77 +767,27 @@ int ha_ndbcluster::ordered_index_scan(const byte *key, uint key_len,
if (!(cursor= op->readTuples(parallelism))) if (!(cursor= op->readTuples(parallelism)))
ERR_RETURN(trans->getNdbError()); ERR_RETURN(trans->getNdbError());
m_active_cursor= cursor; m_active_cursor= cursor;
switch (find_flag) { if (start_key &&
case HA_READ_KEY_EXACT: /* Find first record else error */ set_bounds(op, start_key,
bound_str= "HA_READ_KEY_EXACT"; (start_key->flag == HA_READ_KEY_EXACT) ?
bound_type= NdbOperation::BoundEQ; NdbOperation::BoundEQ :
can_be_handled_by_ndb= TRUE; (start_key->flag == HA_READ_AFTER_KEY) ?
break; NdbOperation::BoundLT :
case HA_READ_KEY_OR_NEXT: /* Record or next record */ NdbOperation::BoundLE))
bound_str= "HA_READ_KEY_OR_NEXT";
bound_type= NdbOperation::BoundLE;
can_be_handled_by_ndb= TRUE;
break;
case HA_READ_KEY_OR_PREV: /* Record or previous */
bound_str= "HA_READ_KEY_OR_PREV";
bound_type= NdbOperation::BoundGE;
can_be_handled_by_ndb= TRUE;
break;
case HA_READ_AFTER_KEY: /* Find next rec. after key-record */
bound_str= "HA_READ_AFTER_KEY";
bound_type= NdbOperation::BoundLT;
can_be_handled_by_ndb= TRUE;
break;
case HA_READ_BEFORE_KEY: /* Find next rec. before key-record */
bound_str= "HA_READ_BEFORE_KEY";
bound_type= NdbOperation::BoundGT;
can_be_handled_by_ndb= TRUE;
break;
case HA_READ_PREFIX: /* Key which as same prefix */
bound_str= "HA_READ_PREFIX";
break;
case HA_READ_PREFIX_LAST: /* Last key with the same prefix */
bound_str= "HA_READ_PREFIX_LAST";
break;
case HA_READ_PREFIX_LAST_OR_PREV:
/* Last or prev key with the same prefix */
bound_str= "HA_READ_PREFIX_LAST_OR_PREV";
break;
default:
bound_str= "UNKNOWN";
break;
}
DBUG_PRINT("info", ("find_flag: %s, bound_type: %d,"
"can_be_handled_by_ndb: %d",
bound_str, bound_type, can_be_handled_by_ndb));
if (!can_be_handled_by_ndb)
DBUG_RETURN(1); DBUG_RETURN(1);
if (end_key &&
(start_key && start_key->flag != HA_READ_KEY_EXACT) &&
// MASV Is it a bug that end_key is not 0
// if start flag is HA_READ_KEY_EXACT
// Set bounds using key data set_bounds(op, end_key,
tot_len= 0; (end_key->flag == HA_READ_AFTER_KEY) ?
key_ptr= (byte *) key; NdbOperation::BoundGE :
key_info= table->key_info + active_index; NdbOperation::BoundGT))
for (i= 0; i < key_info->key_parts; i++) DBUG_RETURN(1);
{
Field* field= key_info->key_part[i].field;
uint32 field_len= field->pack_length();
DBUG_PRINT("info", ("Set index bound on %s",
field->field_name));
DBUG_DUMP("key", (char*)key_ptr, field_len);
if (op->setBound(field->field_name,
bound_type,
key_ptr,
field_len) != 0)
ERR_RETURN(op->getNdbError());
key_ptr+= field_len;
tot_len+= field_len;
if (tot_len >= key_len)
break;
}
// Define attributes to read // Define attributes to read
for (i= 0; i < no_fields; i++) for (i= 0; i < no_fields; i++)
{ {
...@@ -1428,9 +1433,13 @@ int ha_ndbcluster::index_read(byte *buf, ...@@ -1428,9 +1433,13 @@ int ha_ndbcluster::index_read(byte *buf,
#endif #endif
error= unique_index_read(key, key_len, buf); error= unique_index_read(key, key_len, buf);
break; break;
case ORDERED_INDEX: case ORDERED_INDEX:
error= ordered_index_scan(key, key_len, buf, find_flag); key_range start_key;
start_key.key= key;
start_key.length= key_len;
start_key.flag= find_flag;
error= ordered_index_scan(&start_key, 0, false, buf);
break; break;
default: default:
...@@ -1491,6 +1500,44 @@ int ha_ndbcluster::index_last(byte *buf) ...@@ -1491,6 +1500,44 @@ int ha_ndbcluster::index_last(byte *buf)
} }
int ha_ndbcluster::read_range_first(const key_range *start_key,
const key_range *end_key,
bool sorted)
{
int error= 1;
DBUG_ENTER("ha_ndbcluster::read_range_first");
switch (get_index_type(active_index)){
case PRIMARY_KEY_INDEX:
error= pk_read(start_key->key, start_key->length,
table->record[0]);
break;
case UNIQUE_INDEX:
error= unique_index_read(start_key->key, start_key->length,
table->record[0]);
break;
case ORDERED_INDEX:
// Start the ordered index scan and fetch the first row
error= ordered_index_scan(start_key, end_key, sorted,
table->record[0]);
break;
default:
case UNDEFINED_INDEX:
break;
}
DBUG_RETURN(error);
}
int ha_ndbcluster::read_range_next(bool eq_range)
{
DBUG_ENTER("ha_ndbcluster::read_range_next");
DBUG_RETURN(next_result(table->record[0]));
}
int ha_ndbcluster::rnd_init(bool scan) int ha_ndbcluster::rnd_init(bool scan)
{ {
NdbResultSet *cursor= m_active_cursor; NdbResultSet *cursor= m_active_cursor;
......
...@@ -76,6 +76,11 @@ class ha_ndbcluster: public handler ...@@ -76,6 +76,11 @@ class ha_ndbcluster: public handler
int rnd_next(byte *buf); int rnd_next(byte *buf);
int rnd_pos(byte *buf, byte *pos); int rnd_pos(byte *buf, byte *pos);
void position(const byte *record); void position(const byte *record);
int read_range_first(const key_range *start_key,
const key_range *end_key,
bool sorted);
int read_range_next(bool eq_range);
void info(uint); void info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
...@@ -150,9 +155,9 @@ class ha_ndbcluster: public handler ...@@ -150,9 +155,9 @@ class ha_ndbcluster: public handler
byte *buf); byte *buf);
int unique_index_read(const byte *key, uint key_len, int unique_index_read(const byte *key, uint key_len,
byte *buf); byte *buf);
int ordered_index_scan(const byte *key, uint key_len, int ordered_index_scan(const key_range *start_key,
byte *buf, const key_range *end_key,
enum ha_rkey_function find_flag); bool sorted, byte* buf);
int full_table_scan(byte * buf); int full_table_scan(byte * buf);
int next_result(byte *buf); int next_result(byte *buf);
#if 0 #if 0
...@@ -175,6 +180,8 @@ class ha_ndbcluster: public handler ...@@ -175,6 +180,8 @@ class ha_ndbcluster: public handler
int get_ndb_value(NdbOperation*, uint fieldnr, byte *field_ptr); int get_ndb_value(NdbOperation*, uint fieldnr, byte *field_ptr);
int set_primary_key(NdbOperation *op, const byte *key); int set_primary_key(NdbOperation *op, const byte *key);
int set_primary_key(NdbOperation *op); int set_primary_key(NdbOperation *op);
int set_bounds(NdbOperation *ndb_op, const key_range *key,
int bound);
int key_cmp(uint keynr, const byte * old_row, const byte * new_row); int key_cmp(uint keynr, const byte * old_row, const byte * new_row);
void print_results(); void print_results();
......
...@@ -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