Commit 5a14bb2a authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Integrated table->ref_primary_key into table->part_of_key

Fixed bug in UNION
parent ea0523bd
......@@ -321,6 +321,7 @@ static void dump_remote_log_entries(const char* logname)
for(;;)
{
const char *error;
len = net_safe_read(mysql);
if (len == packet_error)
die("Error reading packet from server: %s", mysql_error(mysql));
......@@ -330,8 +331,8 @@ static void dump_remote_log_entries(const char* logname)
len, net->read_pos[5]));
Log_event * ev = Log_event::read_log_event(
(const char*) net->read_pos + 1 ,
len - 1);
if(ev)
len - 1, &error);
if (ev)
{
ev->print(result_file, short_form, last_db);
if(ev->get_type_code() == LOAD_EVENT)
......
......@@ -62,6 +62,7 @@ int heap_write(HP_INFO *info, const byte *record)
info->update|=HA_STATE_AKTIV;
DBUG_RETURN(0);
err:
DBUG_PRINT("info",("Duplicate key: %d",key));
info->errkey= key;
do
{
......
......@@ -284,7 +284,7 @@ static void usage(void)
-?, --help Display this help and exit.\n\
-V, --version Output version information and exit.");
print_defaults("my",load_default_groups);
};
}
/* reads options */
/* Initiates DEBUG - but no debugging here ! */
......
......@@ -269,8 +269,7 @@ DASH72=`$ECHO '-----------------------------------------------------------------
# on binary, use what is installed
if [ x$SOURCE_DIST = x1 ] ; then
MYSQLD="$BASEDIR/sql/mysqld"
if [ -e "$BASEDIR/client/.libs/mysqltest" ] ; then
[ -e "$BASEDIR/client/.libs/lt-mysqltest" ] || $BASEDIR/client/mysqltest -V
if [ -f "$BASEDIR/client/.libs/lt-mysqltest" ] ; then
MYSQL_TEST="$BASEDIR/client/.libs/lt-mysqltest"
else
MYSQL_TEST="$BASEDIR/client/mysqltest"
......@@ -502,7 +501,7 @@ start_master()
#start master
if [ -z "$DO_BENCH" ]
then
master_args="--no-defaults --log-bin=master-bin \
master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin \
--server-id=1 \
--basedir=$MY_BASEDIR \
--port=$MASTER_MYPORT \
......@@ -519,7 +518,8 @@ start_master()
$SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
else
master_args="--no-defaults --log-bin=master-bin --server-id=1 \
master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin \
--server-id=1 \
--basedir=$MY_BASEDIR \
--port=$MASTER_MYPORT \
--datadir=$MASTER_MYDDIR \
......@@ -576,7 +576,8 @@ start_slave()
$RM -f $SLAVE_MYDDIR/log.*
slave_args="--no-defaults $master_info \
--exit-info=256 \
--log-bin=slave-bin --log-slave-updates \
--log-bin=$MYSQL_TEST_DIR/var/log/slave-bin
--log-slave-updates \
--basedir=$MY_BASEDIR \
--datadir=$SLAVE_MYDDIR \
--pid-file=$SLAVE_MYPID \
......
......@@ -70,3 +70,15 @@ pseudo pseudo1 same
joce tsestset 1
joce testtt 1
dekad joce 1
pseudo1
testtt
tsestset
dekad
pseudo1
testtt
tsestset
dekad
pseudo1
testtt
tsestset
1
......@@ -62,4 +62,7 @@ INSERT INTO t1 (pseudo,pseudo1,same) VALUES ('joce', 'testtt', 1),('joce', 'tses
SELECT pseudo FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo FROM t1 WHERE pseudo='joce';
SELECT pseudo1 FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo1 FROM t1 WHERE pseudo='joce';
SELECT * FROM t1 WHERE pseudo1='joce' UNION SELECT * FROM t1 WHERE pseudo='joce' order by pseudo desc;
SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT pseudo FROM t1 WHERE pseudo1='joce';
SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION ALL SELECT pseudo FROM t1 WHERE pseudo1='joce';
SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT 1;
drop table t1;
......@@ -57,7 +57,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_select.h structs.h table.h sql_udf.h hash_filo.h\
lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h \
log_event.h mini_client.h sql_repl.h slave.h \
stacktrace.h sql_sort.h
stacktrace.h sql_sort.h mysql_embed.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
......
......@@ -298,13 +298,21 @@ bool Item::fix_fields(THD *thd,
bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (!field)
if (!field) // If field is not checked
{
Field *tmp;
if (!(tmp=find_field_in_tables(thd,this,tables)))
return 1;
set_field(tmp);
}
else if (thd && thd->set_query_id && field->query_id != thd->query_id)
{
/* We only come here in unions */
TABLE *table=field->table;
field->query_id=thd->query_id;
table->used_fields++;
table->used_keys&=field->part_of_key;
}
return 0;
}
......
......@@ -469,7 +469,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file)
error = "read error";
goto err;
}
if((res = read_log_event(buf, data_len)))
if ((res = read_log_event(buf, data_len, &error)))
res->register_temp_buf(buf);
err:
UNLOCK_MUTEX;
......@@ -481,10 +481,11 @@ Log_event* Log_event::read_log_event(IO_CACHE* file)
return res;
}
Log_event* Log_event::read_log_event(const char* buf, int event_len)
Log_event* Log_event::read_log_event(const char* buf, int event_len,
const char **error)
{
if(event_len < EVENT_LEN_OFFSET ||
(uint)event_len != uint4korr(buf+EVENT_LEN_OFFSET))
if (event_len < EVENT_LEN_OFFSET ||
(uint)event_len != uint4korr(buf+EVENT_LEN_OFFSET))
return NULL; // general sanity check - will fail on a partial read
Log_event* ev = NULL;
......@@ -531,6 +532,7 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len)
if (!ev) return 0;
if (!ev->is_valid())
{
*error= "Found invalid event in binary log";
delete ev;
return 0;
}
......@@ -812,80 +814,92 @@ int Load_log_event::write_data_body(IO_CACHE* file)
if (sql_ex.write_data(file)) return 1;
if (num_fields && fields && field_lens)
{
if(my_b_write(file, (byte*)field_lens, num_fields) ||
my_b_write(file, (byte*)fields, field_block_len))
if (my_b_write(file, (byte*)field_lens, num_fields) ||
my_b_write(file, (byte*)fields, field_block_len))
return 1;
}
return my_b_write(file, (byte*)table_name, table_name_len + 1) ||
my_b_write(file, (byte*)db, db_len + 1) ||
my_b_write(file, (byte*)fname, fname_len);
return (my_b_write(file, (byte*)table_name, table_name_len + 1) ||
my_b_write(file, (byte*)db, db_len + 1) ||
my_b_write(file, (byte*)fname, fname_len));
}
#define WRITE_STR(name) my_b_write(file,(byte*)&name ## _len, 1) || \
my_b_write(file,(byte*)name,name ## _len)
#define OLD_EX_INIT(name) old_ex.##name = *name
static bool write_str(IO_CACHE *file, char *str, byte length)
{
return (my_b_write(file, &length, 1) ||
my_b_write(file, (byte*) str, (int) length));
}
int sql_ex_info::write_data(IO_CACHE* file)
{
if (new_format())
{
return WRITE_STR(field_term) || WRITE_STR(enclosed) ||
WRITE_STR(line_term) || WRITE_STR(line_start) ||
WRITE_STR(escaped) || my_b_write(file,(byte*)&opt_flags,1);
return (write_str(file, field_term, field_term_len) ||
write_str(file, enclosed, enclosed_len) ||
write_str(file, line_term, line_term_len) ||
write_str(file, line_start, line_start_len) ||
write_str(file, escaped, escaped_len) ||
my_b_write(file,(byte*) &opt_flags,1));
}
else
{
old_sql_ex old_ex;
OLD_EX_INIT(field_term);
OLD_EX_INIT(enclosed);
OLD_EX_INIT(line_term);
OLD_EX_INIT(line_start);
OLD_EX_INIT(escaped);
old_ex.opt_flags = opt_flags;
old_ex.empty_flags = empty_flags;
return my_b_write(file,(byte*)&old_ex,sizeof(old_ex));
old_ex.field_term= *field_term;
old_ex.enclosed= *enclosed;
old_ex.line_term= *line_term;
old_ex.line_start= *line_start;
old_ex.escaped= *escaped;
old_ex.opt_flags= opt_flags;
old_ex.empty_flags=empty_flags;
return my_b_write(file, (byte*) &old_ex, sizeof(old_ex));
}
}
#define READ_STR(name) name ## _len = *buf++;\
if (buf >= buf_end) return 0;\
name = buf; \
buf += name ## _len; \
if (buf >= buf_end) return 0;
#define READ_OLD_STR(name) name ## _len = 1; \
name = buf++; \
if (buf >= buf_end) return 0;
#define FIX_OLD_LEN(name,NAME) if (empty_flags & NAME ## _EMPTY) \
name ## _len = 0
static inline int read_str(char * &buf, char *buf_end, char * &str,
uint8 &len)
{
if (buf + (uint) (uchar) *buf >= buf_end)
return 1;
len = (uint8) *buf;
str= buf+1;
buf+= (uint) len+1;
return 0;
}
char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
{
cached_new_format = use_new_format;
if (use_new_format)
{
READ_STR(field_term);
READ_STR(enclosed);
READ_STR(line_term);
READ_STR(line_start);
READ_STR(escaped);
empty_flags=0;
if (read_str(buf, buf_end, field_term, field_term_len) ||
read_str(buf, buf_end, enclosed, enclosed_len) ||
read_str(buf, buf_end, line_term, line_term_len) ||
read_str(buf, buf_end, line_start, line_start_len) ||
read_str(buf, buf_end, escaped, escaped_len))
return 0;
opt_flags = *buf++;
}
else
{
READ_OLD_STR(field_term);
READ_OLD_STR(enclosed);
READ_OLD_STR(line_term);
READ_OLD_STR(line_start);
READ_OLD_STR(escaped);
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
*field_term=*buf++;
*enclosed= *buf++;
*line_term= *buf++;
*line_start=*buf++;
*escaped= *buf++;
opt_flags = *buf++;
empty_flags = *buf++;
FIX_OLD_LEN(field_term,FIELD_TERM);
FIX_OLD_LEN(enclosed,ENCLOSED);
FIX_OLD_LEN(line_term,LINE_TERM);
FIX_OLD_LEN(line_start,LINE_START);
FIX_OLD_LEN(escaped,ESCAPED);
empty_flags=*buf++;
if (empty_flags & FIELD_TERM_EMPTY)
field_term_len=0;
if (empty_flags & ENCLOSED_EMPTY)
enclosed_len=0;
if (empty_flags & LINE_TERM_EMPTY)
line_term_len=0;
if (empty_flags & LINE_START_EMPTY)
line_start_len=0;
if (empty_flags & ESCAPED_EMPTY)
escaped_len=0;
}
return buf;
}
......@@ -1271,6 +1285,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len):
block = (char*)buf + block_offset;
block_len = len - block_offset;
}
#ifdef MYSQL_CLIENT
void Create_file_log_event::print(FILE* file, bool short_form,
char* last_db)
......@@ -1553,20 +1569,16 @@ int Load_log_event::exec_event(NET* net, struct st_master_info* mi)
handle_dup = DUP_REPLACE;
sql_exchange ex((char*)fname, sql_ex.opt_flags &&
DUMPFILE_FLAG );
#define SET_EX(name) String name(sql_ex.name,sql_ex.name ## _len);\
ex.name = &name;
SET_EX(field_term);
SET_EX(enclosed);
SET_EX(line_term);
SET_EX(line_start);
SET_EX(escaped);
String field_term(sql_ex.field_term,sql_ex.field_term_len);
String enclosed(sql_ex.enclosed,sql_ex.enclosed_len);
String line_term(sql_ex.line_term,sql_ex.line_term_len);
String line_start(sql_ex.line_start,sql_ex.line_start_len);
String escaped(sql_ex.escaped,sql_ex.escaped_len);
ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
if(sql_ex.empty_flags & FIELD_TERM_EMPTY)
if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
ex.field_term->length(0);
ex.skip_lines = skip_lines;
List<Item> fields;
set_fields(fields);
......@@ -1862,10 +1874,3 @@ int Execute_load_log_event::exec_event(struct st_master_info* mi)
#endif
......@@ -272,7 +272,8 @@ class Log_event
#else // avoid having to link mysqlbinlog against libpthread
static Log_event* read_log_event(IO_CACHE* file);
#endif
static Log_event* read_log_event(const char* buf, int event_len);
static Log_event* read_log_event(const char* buf, int event_len,
const char **error);
const char* get_type_str();
#ifndef MYSQL_CLIENT
......@@ -567,9 +568,10 @@ class Create_file_log_event: public Load_log_event
uint file_id;
#ifndef MYSQL_CLIENT
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
const char* table_name_arg,
List<Item>& fields_arg, enum enum_duplicates handle_dup,
char* block_arg, uint block_len_arg);
const char* table_name_arg,
List<Item>& fields_arg,
enum enum_duplicates handle_dup,
char* block_arg, uint block_len_arg);
#endif
Create_file_log_event(const char* buf, int event_len);
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Defines that are unique to the embedded version of MySQL */
#ifdef EMBEDDED_LIBRARY
/* Things we don't need in the embedded version of MySQL */
#undef HAVE_PSTACK /* No stacktrace */
#undef HAVE_DLOPEN /* No udf functions */
#endif /* EMBEDDED_LIBRARY */
......@@ -18,9 +18,10 @@
#define _MYSQL_PRIV_H
#include <my_global.h>
#include "mysql_embed.h"
#include <my_sys.h>
#include <m_string.h>
#include "mysql_version.h"
#include <mysql_version.h>
#include <hash.h>
#include <signal.h>
#include <thr_lock.h>
......
......@@ -305,7 +305,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
key>>=1;
ref->key_length=0;
ref->key=idx;
if (field->part_of_key & ((table_map) 1 << idx))
if (field->part_of_key & ((key_map) 1 << idx))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
......@@ -350,7 +350,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
{
ref->key_length= (uint) (key_ptr-ref->key_buff);
ref->key=idx;
if (field->part_of_key & ((table_map) 1 << idx))
if (field->part_of_key & ((key_map) 1 << idx))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
......
......@@ -934,8 +934,9 @@ point. If you are sure that your master is ok, run this query manually on the\
static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
{
const char *error_msg;
Log_event * ev = Log_event::read_log_event((const char*)net->read_pos + 1,
event_len);
event_len, &error_msg);
if (ev)
{
int type_code = ev->get_type_code();
......
......@@ -160,7 +160,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
if (table)
continue;
if (!(*start_list = (OPEN_TABLE_LIST *)
sql_alloc(sizeof(OPEN_TABLE_LIST)+entry->key_length)))
sql_alloc(sizeof(*start_list)+entry->key_length)))
{
open_list=0; // Out of memory
break;
......@@ -172,6 +172,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
(*start_list)->locked= entry->locked_by_name ? 1 : 0;
start_list= &(*start_list)->next;
}
*start_list=0;
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(open_list);
}
......@@ -1579,13 +1580,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
{
field->query_id=thd->query_id;
table->used_fields++;
if (field->part_of_key)
{
if (!(field->part_of_key & table->ref_primary_key))
table->used_keys&=field->part_of_key;
}
else
table->used_keys=0;
table->used_keys&=field->part_of_key;
}
else
thd->dupp_field=field;
......@@ -1655,7 +1650,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
for (; tables ; tables=tables->next)
{
Field *field=find_field_in_table(thd,tables->table,name,length,
grant_option && !thd->master_access, allow_rowid);
grant_option &&
!thd->master_access, allow_rowid);
if (field)
{
if (field == WRONG_GRANT)
......@@ -1879,14 +1875,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
if (field->query_id == thd->query_id)
thd->dupp_field=field;
field->query_id=thd->query_id;
if (field->part_of_key)
{
if (!(field->part_of_key & table->ref_primary_key))
table->used_keys&=field->part_of_key;
}
else
table->used_keys=0;
table->used_keys&=field->part_of_key;
}
/* All fields are used */
table->used_fields=table->fields;
......@@ -1967,20 +1956,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
/* Mark field used for table cache */
t1->field[i]->query_id=t2->field[j]->query_id=thd->query_id;
cond_and->list.push_back(tmp);
if ((tmp_map=t1->field[i]->part_of_key))
{
if (!(tmp_map & t1->ref_primary_key))
t1->used_keys&=tmp_map;
}
else
t1->used_keys=0;
if ((tmp_map=t2->field[j]->part_of_key))
{
if (!(tmp_map & t2->ref_primary_key))
t2->used_keys&=tmp_map;
}
else
t2->used_keys=0;
t1->used_keys&= t1->field[i]->part_of_key;
t2->used_keys&= t2->field[j]->part_of_key;
break;
}
}
......
......@@ -31,7 +31,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
ORDER *order;
List<Item> item_list;
TABLE *table;
TABLE_LIST *first_table, result_table_list;
TABLE_LIST result_table_list;
TMP_TABLE_PARAM tmp_table_param;
select_union *union_result;
int res;
......@@ -75,9 +75,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
{
Item *item;
List_iterator<Item> it(lex->select_lex.item_list);
TABLE_LIST *first_table= (TABLE_LIST*) lex->select_lex.table_list.first;
/* Create a list of items that will be in the result set */
first_table= (TABLE_LIST*) lex->select_lex.table_list.first;
while ((item= it++))
if (item_list.push_back(item))
DBUG_RETURN(-1);
......
......@@ -455,8 +455,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (key == primary_key)
{
field->flags|= PRI_KEY_FLAG;
/*
If this field is part of the primary key and all keys contains
the primary key, then we can use any key to find this column
*/
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
field->part_of_key|= ((key_map) 1 << primary_key);
field->part_of_key= outparam->keys_in_use;
}
if (field->key_length() != key_part->length)
{
......@@ -480,8 +484,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(outparam->keys_in_use & ((key_map) 1 << primary_key)))
{
outparam->primary_key=primary_key;
if (outparam->file->option_flag() & HA_PRIMARY_KEY_IN_READ_INDEX)
outparam->ref_primary_key= (key_map) 1 << primary_key;
/*
If we are using an integer as the primary key then allow the user to
refer to it as '_rowid'
......
......@@ -117,7 +117,7 @@ struct st_table {
byte *record_pointers; /* If sorted in memory */
ha_rows found_records; /* How many records in sort */
ORDER *group;
key_map quick_keys, used_keys, ref_primary_key;
key_map quick_keys, used_keys;
ha_rows quick_rows[MAX_KEY];
uint quick_key_parts[MAX_KEY];
key_part_map const_key_parts[MAX_KEY];
......
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