Commit 4e886689 authored by unknown's avatar unknown

These are actually two changesets. One for splitting LEX in two and

the other for multi-table delete


sql/filesort.cc:
  Fixed some bugs for Unique class
sql/item.cc:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc
sql/item_sum.cc:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc
sql/mysql_priv.h:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc
sql/sql_class.h:
  Adding multi table delete
sql/sql_delete.cc:
  Added multi-table delete
sql/sql_lex.cc:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc
sql/sql_lex.h:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc
sql/sql_parse.cc:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc, plus added multi-table delete
sql/sql_select.cc:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc
sql/sql_update.cc:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc
sql/sql_yacc.yy:
  Changes caused by splitting lex into two parts, in order to 
  implement UNION's etc, plus added multi-table delete
sql/uniques.cc:
  Fixed some bugs in duplicate stripping
BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parent 020160f8
......@@ -15,3 +15,4 @@ serg@serg.mysql.com
tim@threads.polyesthetic.msg
tim@work.mysql.com
tonu@x3.internalnet
Sinisa@sinisa.nasamreza.org
......@@ -739,7 +739,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
buffpek=(BUFFPEK*) queue_top(&queue);
if (cmp) // Remove duplicates
{
if (!cmp(&sort_length, param->unique_buff, (uchar*) buffpek->key))
// Was if (!cmp(&sort_length, param->unique_buff, (uchar**) buffpek->key))
if (!cmp(&sort_length, &(param->unique_buff), (uchar**) &buffpek->key))
goto skip_duplicate;
memcpy(param->unique_buff, (uchar*) buffpek->key,sort_length);
}
......
......@@ -561,7 +561,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (!ref)
{
if (!(ref=find_item_in_list(this,thd->lex.item_list)))
if (!(ref=find_item_in_list(this,thd->lex.select->item_list)))
return 1;
max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null;
......
......@@ -883,7 +883,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
tmp_table_param->cleanup();
}
if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
0, 0, current_lex->options | thd->options)))
0, 0, current_lex->select->options | thd->options)))
return 1;
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
table->no_rows=1;
......
......@@ -667,7 +667,7 @@ extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
inline bool add_item_to_list(Item *item)
{
return current_lex->item_list.push_back(item);
return current_lex->select->item_list.push_back(item);
}
inline bool add_value_to_list(Item *value)
{
......@@ -675,11 +675,11 @@ inline bool add_value_to_list(Item *value)
}
inline bool add_order_to_list(Item *item,bool asc)
{
return add_to_list(current_lex->order_list,item,asc);
return add_to_list(current_lex->select->order_list,item,asc);
}
inline bool add_group_to_list(Item *item,bool asc)
{
return add_to_list(current_lex->group_list,item,asc);
return add_to_list(current_lex->select->group_list,item,asc);
}
inline void mark_as_null_row(TABLE *table)
{
......
......@@ -465,6 +465,32 @@ public:
bool send_eof();
};
class multi_delete : public select_result {
TABLE_LIST *delete_tables, *table_being_deleted;
IO_CACHE **tempfiles;
thr_lock_type lock_option;
ulong deleted;
byte *dup_checking, wrong_record[MAX_REFLENGTH], *memory_lane;
int num_of_tables, error;
bool do_delete;
THD *thd;
public:
multi_delete(TABLE_LIST *dt, thr_lock_type o, uint n)
: delete_tables (dt), lock_option(o), deleted(0), num_of_tables(n), error(0)
{
memset(wrong_record,'\xFF',MAX_REFLENGTH);
thd = current_thd; do_delete = false;
}
~multi_delete();
int prepare(List<Item> &list);
bool send_fields(List<Item> &list,
uint flag) { return 0; }
bool send_data(List<Item> &items);
void send_error(uint errcode,const char *err);
int do_deletes (bool from_send_error);
bool send_eof();
};
class select_insert :public select_result {
protected:
......@@ -578,19 +604,18 @@ class Unique :public Sql_alloc
public:
ulong elements;
Unique(qsort_cmp2 comp_func, uint size, ulong max_in_memory_size_arg);
Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
uint size, ulong max_in_memory_size_arg);
~Unique();
inline bool Unique::unique_add(gptr ptr)
{
if (tree.elements_in_tree > max_elements && flush())
return 1;
return tree_insert(&tree,ptr,0);
return !tree_insert(&tree,ptr,0);
}
bool get(TABLE *table);
friend int unique_write_to_file(gptr key, Unique *unique,
element_count count);
friend int unique_write_to_ptrs(gptr key, Unique *unique,
element_count count);
friend int unique_write_to_file(gptr key, element_count count, Unique *unique);
friend int unique_write_to_ptrs(gptr key, element_count count, Unique *unique);
};
This diff is collapsed.
......@@ -142,11 +142,11 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->next_state=STATE_START;
lex->end_of_query=(lex->ptr=buf)+length;
lex->yylineno = 1;
lex->create_refs=lex->in_comment=0;
lex->select->create_refs=lex->in_comment=0;
lex->length=0;
lex->in_sum_expr=0;
lex->expr_list.empty();
lex->ftfunc_list.empty();
lex->select->in_sum_expr=0;
lex->select->expr_list.empty();
lex->select->ftfunc_list.empty();
lex->convert_set=(lex->thd=thd)->convert_set;
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->client_capabilities & CLIENT_IGNORE_SPACE);
......@@ -155,7 +155,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
void lex_end(LEX *lex)
{
lex->expr_list.delete_elements(); // If error when parsing sql-varargs
lex->select->expr_list.delete_elements(); // If error when parsing sql-varargs
x_free(lex->yacc_yyss);
x_free(lex->yacc_yyvs);
}
......
......@@ -54,7 +54,8 @@ enum enum_sql_command {
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS,
SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
SQLCOM_MULTI_DELETE
};
enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
......@@ -94,39 +95,57 @@ typedef struct st_lex_master_info
ulonglong pos;
} LEX_MASTER_INFO;
enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE};
/* The state of the lex parsing for selects */
typedef struct st_select_lex {
enum sub_select_type linkage;
uint select_number; /* For Item_select */
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
Item *where,*having;
ha_rows select_limit,offset_limit;
ulong options;
List<List_item> expr_list;
List<List_item> when_list;
SQL_LIST order_list,table_list,group_list;
List<Item> item_list;
List<String> interval_list,use_index, *use_index_ptr, ignore_index, *ignore_index_ptr;
List<Item_func_match> ftfunc_list;
uint in_sum_expr, sort_default;
bool create_refs;
st_select_lex *next;
} SELECT_LEX;
/* The state of the lex parsing. This is saved in the THD struct */
typedef struct st_lex {
uint yylineno,yytoklen; /* Simulate lex */
LEX_YYSTYPE yylval;
SELECT_LEX select_lex, *select;
uchar *ptr,*tok_start,*tok_end,*end_of_query;
char *length,*dec,*change,*name;
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
char *backup_dir; /* For RESTORE/BACKUP */
char* to_log; /* For PURGE MASTER LOGS TO */
String *wild;
sql_exchange *exchange;
ha_rows select_limit,offset_limit;
List<List_item> expr_list;
List<List_item> when_list;
List<List_item> many_values;
List<key_part_spec> col_list;
List<Alter_drop> drop_list;
List<Alter_column> alter_list;
List<String> interval_list,use_index,*use_index_ptr,
ignore_index, *ignore_index_ptr;
List<String> interval_list;
List<st_lex_user> users_list;
List<LEX_COLUMN> columns;
List<Key> key_list;
List<create_field> create_list;
List<Item> item_list,*insert_list,field_list,value_list;
List<Item_func_match> ftfunc_list;
SQL_LIST order_list,table_list,group_list,proc_list;
List<Item> *insert_list,field_list,value_list;
List<List_item> many_values;
SQL_LIST proc_list, auxilliary_table_list;
TYPELIB *interval;
create_field *last_field;
Item *where,*having,*default_value;
Item *default_value;
CONVERT *convert_set;
LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs;
......@@ -136,7 +155,6 @@ typedef struct st_lex {
HA_CREATE_INFO create_info;
LEX_MASTER_INFO mi; // used by CHANGE MASTER
ulong thread_id,type;
ulong options;
ulong gemini_spin_retries;
enum_sql_command sql_command;
enum lex_states next_state;
......@@ -145,9 +163,9 @@ typedef struct st_lex {
enum enum_ha_read_modes ha_read_mode;
enum ha_rkey_function ha_rkey_mode;
enum enum_enable_or_disable alter_keys_onoff;
uint in_sum_expr,grant,grant_tot_col,which_columns, sort_default;
uint grant,grant_tot_col,which_columns;
thr_lock_type lock_option;
bool create_refs,drop_primary,drop_if_exists,local_file;
bool drop_primary,drop_if_exists,local_file;
bool in_comment,ignore_space,verbose,simple_alter;
} LEX;
......
This diff is collapsed.
......@@ -2478,7 +2478,7 @@ make_join_readinfo(JOIN *join,uint options)
/* These init changes read_record */
if (tab->use_quick == 2)
{
join->thd->lex.options|=QUERY_NO_GOOD_INDEX_USED;
join->thd->lex.select_lex.options|=QUERY_NO_GOOD_INDEX_USED;
tab->read_first_record= join_init_quick_read_record;
statistic_increment(select_range_check_count, &LOCK_status);
}
......@@ -2493,7 +2493,7 @@ make_join_readinfo(JOIN *join,uint options)
}
else
{
join->thd->lex.options|=QUERY_NO_INDEX_USED;
join->thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
statistic_increment(select_scan_count, &LOCK_status);
}
}
......@@ -2505,7 +2505,7 @@ make_join_readinfo(JOIN *join,uint options)
}
else
{
join->thd->lex.options|=QUERY_NO_INDEX_USED;
join->thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
statistic_increment(select_full_join_count, &LOCK_status);
}
}
......@@ -3920,7 +3920,7 @@ bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
thd->proc_info="converting HEAP to MyISAM";
if (create_myisam_tmp_table(&new_table,param,
thd->lex.options | thd->options))
thd->lex.select_lex.options | thd->options))
goto err2;
if (open_tmp_table(&new_table))
goto err1;
......@@ -6647,7 +6647,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
DBUG_ENTER("select_describe");
/* Don't log this into the slow query log */
join->thd->lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
join->thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
field_list.push_back(new Item_empty_string("table",NAME_LEN));
field_list.push_back(new Item_empty_string("type",10));
field_list.push_back(item=new Item_empty_string("possible_keys",
......@@ -6806,7 +6806,7 @@ static void describe_info(THD *thd, const char *info)
String *packet= &thd->packet;
/* Don't log this into the slow query log */
thd->lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
field_list.push_back(new Item_empty_string("Comment",80));
if (send_fields(thd,field_list,1))
return; /* purecov: inspected */
......
......@@ -128,7 +128,7 @@ int mysql_update(THD *thd,
/* If running in safe sql mode, don't allow updates without keys */
if (!table->quick_keys)
{
thd->lex.options|=QUERY_NO_INDEX_USED;
thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR)
{
delete select;
......
This diff is collapsed.
......@@ -34,11 +34,14 @@
#include "mysql_priv.h"
#include "sql_sort.h"
Unique::Unique(qsort_cmp2 comp_func, uint size, ulong max_in_memory_size_arg)
Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
uint size, ulong max_in_memory_size_arg)
:max_in_memory_size(max_in_memory_size_arg),elements(0)
{
my_b_clear(&file);
init_tree(&tree, max_in_memory_size / 16, size, comp_func, 0, 0);
tree.cmp_arg=comp_func_fixed_arg;
/* If the following fail's the next add will also fail */
init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16);
max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size);
......@@ -69,12 +72,14 @@ bool Unique::flush()
}
int unique_write_to_file(gptr key, Unique *unique, element_count count)
int unique_write_to_file(gptr key, element_count count, Unique *unique)
{
if (!my_b_inited(&unique->file) && open_cached_file(&unique->file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
return 1;
return my_b_write(&unique->file, key, unique->tree.size_of_element) ? 1 : 0;
}
int unique_write_to_ptrs(gptr key, Unique *unique, element_count count)
int unique_write_to_ptrs(gptr key, element_count count, Unique *unique)
{
memcpy(unique->record_pointers, key, unique->tree.size_of_element);
unique->record_pointers+=unique->tree.size_of_element;
......@@ -109,7 +114,7 @@ bool Unique::get(TABLE *table)
IO_CACHE *outfile=table->io_cache, tempfile;
BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
uint maxbuffer= file_ptrs.elements;
uint maxbuffer= file_ptrs.elements - 1; // I added -1 .....
uchar *sort_buffer;
my_off_t save_pos;
bool error=1;
......@@ -117,13 +122,16 @@ bool Unique::get(TABLE *table)
my_b_clear(&tempfile);
/* Open cached file if it isn't open */
if (!outfile) outfile= (IO_CACHE *) sql_calloc(sizeof(IO_CACHE));
if (! my_b_inited(outfile) &&
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
MYF(MY_WME)))
return 1;
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
sort_param.keys=elements;
// sort_param.keys=elements;
sort_param.max_rows= elements;
sort_param.examined_rows=0;
sort_param.sort_form=table;
sort_param.sort_length=sort_param.ref_length=tree.size_of_element;
sort_param.keys= max_in_memory_size / sort_param.sort_length;
......
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