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 {
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:
......@@ -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
*********************************************************************/
......
......@@ -22,9 +22,9 @@ done
stop_default_ndbcluster() {
if [ ! -f $pidfile ] ; then
exit 0
fi
#if [ ! -f $pidfile ] ; then
# exit 0
#fi
if [ ! -f $cfgfile ] ; then
echo "$cfgfile missing"
......@@ -43,8 +43,11 @@ echo "all stop" | $exec_mgmtclient
sleep 5
kill `cat $pidfile`
rm $pidfile
if [ -f $pidfile ] ; then
kill `cat $pidfile`
rm $pidfile
fi
}
stop_default_ndbcluster
......
......@@ -119,3 +119,72 @@ select * from t1 order by a;
a b c
4 5 12
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;
# 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;
update t1 set c = 10 where b >= 6;
select * from t1 order by a;
......@@ -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);
# MASV delete from t1 where b = 3;
delete from t1 where b = 3;
select * from t1 order by a;
delete from t1 where b >= 6;
select * from t1 order by a;
......@@ -97,11 +97,16 @@ 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;
select * from t1 where b<=5;
#select * from t1 where b<=5 and c=0;
#select * from t1 where b=4 and c<=5;
select * from t1 where b<=4 and c<=5;
# MASV select * from t1 where b<=5 and c=0 or b<=5 and c=2;
select * from t1 where b<=5 order by a;
select * from t1 where b<=5 and c=0;
insert into t1 values (19,4, 0);
select * from t1 where b<=5 and c=0;
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;
This diff is collapsed.
......@@ -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
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
cat $fill_help_tables
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
) | eval "$mysqld $defaults $mysqld_opt --bootstrap --skip-grant-tables \
--basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $args"
then
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:"
......
......@@ -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
*/
int ha_ndbcluster::ordered_index_scan(const byte *key, uint key_len,
byte *buf,
enum ha_rkey_function find_flag)
int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
const key_range *end_key,
bool sorted, byte* buf)
{
uint no_fields= table->fields;
uint tot_len, i;
uint i;
NdbConnection *trans= m_active_trans;
NdbResultSet *cursor= m_active_cursor;
NdbScanOperation *op;
const char *bound_str= NULL;
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;
DBUG_ENTER("ordered_index_scan");
DBUG_PRINT("enter", ("index: %u", active_index));
......@@ -713,75 +768,25 @@ int ha_ndbcluster::ordered_index_scan(const byte *key, uint key_len,
ERR_RETURN(trans->getNdbError());
m_active_cursor= cursor;
switch (find_flag) {
case HA_READ_KEY_EXACT: /* Find first record else error */
bound_str= "HA_READ_KEY_EXACT";
bound_type= NdbOperation::BoundEQ;
can_be_handled_by_ndb= TRUE;
break;
case HA_READ_KEY_OR_NEXT: /* Record or next record */
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)
if (start_key &&
set_bounds(op, start_key,
(start_key->flag == HA_READ_KEY_EXACT) ?
NdbOperation::BoundEQ :
(start_key->flag == HA_READ_AFTER_KEY) ?
NdbOperation::BoundLT :
NdbOperation::BoundLE))
DBUG_RETURN(1);
// Set bounds using key data
tot_len= 0;
key_ptr= (byte *) key;
key_info= table->key_info + active_index;
for (i= 0; i < key_info->key_parts; i++)
{
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 (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
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;
}
set_bounds(op, end_key,
(end_key->flag == HA_READ_AFTER_KEY) ?
NdbOperation::BoundGE :
NdbOperation::BoundGT))
DBUG_RETURN(1);
// Define attributes to read
for (i= 0; i < no_fields; i++)
......@@ -1430,7 +1435,11 @@ int ha_ndbcluster::index_read(byte *buf,
break;
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;
default:
......@@ -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)
{
NdbResultSet *cursor= m_active_cursor;
......
......@@ -76,6 +76,11 @@ class ha_ndbcluster: public handler
int rnd_next(byte *buf);
int rnd_pos(byte *buf, byte *pos);
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);
int extra(enum ha_extra_function operation);
......@@ -150,9 +155,9 @@ class ha_ndbcluster: public handler
byte *buf);
int unique_index_read(const byte *key, uint key_len,
byte *buf);
int ordered_index_scan(const byte *key, uint key_len,
byte *buf,
enum ha_rkey_function find_flag);
int ordered_index_scan(const key_range *start_key,
const key_range *end_key,
bool sorted, byte* buf);
int full_table_scan(byte * buf);
int next_result(byte *buf);
#if 0
......@@ -175,6 +180,8 @@ class ha_ndbcluster: public handler
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);
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);
void print_results();
......
......@@ -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--;
......
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