Commit b8674a46 authored by paul@ice.snake.net's avatar paul@ice.snake.net

Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1

into ice.snake.net:/Volumes/ice2/MySQL/bk/mysql-4.1
parents d3031366 403001ff
...@@ -63,6 +63,7 @@ jani@ua167d18.elisa.omakaista.fi ...@@ -63,6 +63,7 @@ jani@ua167d18.elisa.omakaista.fi
jani@ua72d24.elisa.omakaista.fi jani@ua72d24.elisa.omakaista.fi
jcole@abel.spaceapes.com jcole@abel.spaceapes.com
jcole@main.burghcom.com jcole@main.burghcom.com
jcole@mugatu.jcole.us
jcole@mugatu.spaceapes.com jcole@mugatu.spaceapes.com
jcole@sarvik.tfr.cafe.ee jcole@sarvik.tfr.cafe.ee
jcole@tetra.spaceapes.com jcole@tetra.spaceapes.com
......
...@@ -330,10 +330,18 @@ SOURCE=.\my_gethostbyname.c ...@@ -330,10 +330,18 @@ SOURCE=.\my_gethostbyname.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\my_gethwaddr.c
# End Source File
# Begin Source File
SOURCE=.\my_getopt.c SOURCE=.\my_getopt.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\my_getsystime.c
# End Source File
# Begin Source File
SOURCE=.\my_getwd.c SOURCE=.\my_getwd.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -711,10 +711,6 @@ SOURCE=.\nt_servc.h ...@@ -711,10 +711,6 @@ SOURCE=.\nt_servc.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\opt_ft.cpp
# End Source File
# Begin Source File
SOURCE=.\opt_range.cpp SOURCE=.\opt_range.cpp
!IF "$(CFG)" == "mysqld - Win32 Release" !IF "$(CFG)" == "mysqld - Win32 Release"
......
...@@ -185,6 +185,12 @@ struct st_mysql_options { ...@@ -185,6 +185,12 @@ struct st_mysql_options {
char *client_ip; char *client_ip;
/* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */ /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
my_bool secure_auth; my_bool secure_auth;
/* function pointers for local infile support */
int (*local_infile_init)(void **, char *);
int (*local_infile_read)(void *, char *, uint);
int (*local_infile_end)(void *);
int (*local_infile_error)(void *, char *, uint);
}; };
enum mysql_status enum mysql_status
...@@ -384,6 +390,21 @@ my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, ...@@ -384,6 +390,21 @@ my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
unsigned long length); unsigned long length);
/* local infile support */
#define LOCAL_INFILE_ERROR_LEN 512
int
mysql_set_local_infile_handler(MYSQL *mysql,
int (*local_infile_init)(void **, char *),
int (*local_infile_read)(void *, char *, uint),
int (*local_infile_end)(void *),
int (*local_infile_error)(void *, char *, uint));
void
mysql_set_local_infile_default(MYSQL *mysql);
/* /*
enable/disable parsing of all queries to decide if they go on master or enable/disable parsing of all queries to decide if they go on master or
slave slave
......
...@@ -23,7 +23,7 @@ extern my_string mysql_unix_port; ...@@ -23,7 +23,7 @@ extern my_string mysql_unix_port;
sig_handler pipe_sig_handler(int sig __attribute__((unused))); sig_handler pipe_sig_handler(int sig __attribute__((unused)));
void read_user_name(char *name); void read_user_name(char *name);
my_bool send_file_to_server(MYSQL *mysql, const char *filename); my_bool handle_local_infile(MYSQL *mysql, const char *net_filename);
/* /*
Let the user specify that we don't want SIGPIPE; This doesn't however work Let the user specify that we don't want SIGPIPE; This doesn't however work
......
...@@ -794,35 +794,55 @@ void read_user_name(char *name) ...@@ -794,35 +794,55 @@ void read_user_name(char *name)
#endif #endif
my_bool send_file_to_server(MYSQL *mysql, const char *filename) my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
{ {
int fd, readcount;
my_bool result= 1; my_bool result= 1;
uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE); uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
char *buf, tmp_name[FN_REFLEN];
NET *net= &mysql->net; NET *net= &mysql->net;
DBUG_ENTER("send_file_to_server"); int error;
int readcount;
void *li_ptr; /* pass state to local_infile functions */
char *buf = NULL; /* buffer to be filled by local_infile_read */
char *filename = NULL; /* local copy of filename arg */
if (!(buf=my_malloc(packet_length,MYF(0)))) DBUG_ENTER("handle_local_infile");
/* check that we've got valid callback functions */
if (!((mysql->options.local_infile_init) &&
(mysql->options.local_infile_read) &&
(mysql->options.local_infile_end) &&
(mysql->options.local_infile_error)))
{ {
strmov(net->sqlstate, unknown_sqlstate); /* if any of the functions is invalid, set the default */
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY)); mysql_set_local_infile_default(mysql);
DBUG_RETURN(1);
} }
fn_format(tmp_name,filename,"","",4); /* Convert to client format */ /* copy filename into local memory and allocate read buffer */
if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) if ((!(filename = my_strdup(net_filename, MYF(0)))) ||
(!(buf=my_malloc(packet_length, MYF(0)))))
goto oom;
/* initialize local infile (open file, usually) */
if ( (error = (*mysql->options.local_infile_init)(&li_ptr, filename)) )
{ {
my_net_write(net,"",0); /* Server needs one packet */ my_net_write(net,"",0); /* Server needs one packet */
net_flush(net); net_flush(net);
if(error < 0)
goto oom;
strmov(net->sqlstate, unknown_sqlstate); strmov(net->sqlstate, unknown_sqlstate);
net->last_errno=EE_FILENOTFOUND; net->last_errno=error;
my_snprintf(net->last_error,sizeof(net->last_error)-1, (*mysql->options.local_infile_error)(li_ptr,
EE(net->last_errno),tmp_name, errno); net->last_error,
sizeof(net->last_error)-1);
goto err; goto err;
} }
while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0) /* read blocks of data from local infile callback */
while ( (readcount =
(*mysql->options.local_infile_read)(li_ptr,
buf,
packet_length) ) > 0)
{ {
if (my_net_write(net,buf,readcount)) if (my_net_write(net,buf,readcount))
{ {
...@@ -833,6 +853,7 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename) ...@@ -833,6 +853,7 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename)
goto err; goto err;
} }
} }
/* Send empty packet to mark end of file */ /* Send empty packet to mark end of file */
if (my_net_write(net,"",0) || net_flush(net)) if (my_net_write(net,"",0) || net_flush(net))
{ {
...@@ -841,21 +862,136 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename) ...@@ -841,21 +862,136 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename)
sprintf(net->last_error,ER(net->last_errno),errno); sprintf(net->last_error,ER(net->last_errno),errno);
goto err; goto err;
} }
if (readcount < 0) if (readcount < 0)
{ {
strmov(net->sqlstate, unknown_sqlstate); strmov(net->sqlstate, unknown_sqlstate);
net->last_errno=EE_READ; /* the errmsg for not entire file read */ net->last_errno=EE_READ; /* the errmsg for not entire file read */
my_snprintf(net->last_error,sizeof(net->last_error)-1, my_snprintf(net->last_error,sizeof(net->last_error)-1,
tmp_name,errno); filename, errno);
goto err; goto err;
} }
result=0; /* Ok */ result=0; /* Ok */
err: err:
if (fd >= 0) /* free up memory allocated with _init, usually */
(void) my_close(fd,MYF(0)); (*mysql->options.local_infile_end)(li_ptr);
my_free(buf,MYF(0));
my_free(filename, MYF(0));
my_free(buf, MYF(0));
DBUG_RETURN(result); DBUG_RETURN(result);
oom:
/* out of memory */
my_free(filename, MYF(MY_ALLOW_ZERO_PTR));
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
DBUG_RETURN(1);
}
typedef struct default_local_infile_st {
int fd;
int error_num;
char error_msg[LOCAL_INFILE_ERROR_LEN];
} default_local_infile_data;
int
default_local_infile_init(void **ptr, char *filename)
{
default_local_infile_data *data;
if (!(*ptr= data= ((default_local_infile_data *)
my_malloc(sizeof(default_local_infile_data), MYF(0)))))
return -1; /* out of memory */
*ptr = data; /* save the struct, we need it to return an error */
data->error_msg[0]= 0;
data->error_num= 0;
if ((data->fd = my_open(filename, O_RDONLY, MYF(0))) < 0)
{
my_snprintf(data->error_msg, sizeof(data->error_msg)-1,
EE(EE_FILENOTFOUND), filename, errno);
return data->error_num=errno; /* error */
}
return 0; /* ok */
}
int
default_local_infile_read(void *ptr, char *buf, uint buf_len)
{
default_local_infile_data *data = (default_local_infile_data *) ptr;
return ((int) my_read(data->fd, (byte *)buf, buf_len, MYF(0)));
}
int
default_local_infile_end(void *ptr)
{
default_local_infile_data *data = (default_local_infile_data *) ptr;
if(data)
{
my_close(data->fd, MYF(0));
my_free(ptr, MYF(0));
}
return 0;
}
int
default_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
{
default_local_infile_data *data = (default_local_infile_data *) ptr;
if(data) {
strmake(error_msg, data->error_msg, error_msg_len);
return data->error_num;
}
else
{
strmake(error_msg, "Internal error", error_msg_len);
return 0;
}
}
int
mysql_set_local_infile_handler(MYSQL *mysql,
int (*local_infile_init)(void **, char *),
int (*local_infile_read)(void *, char *, uint),
int (*local_infile_end)(void *),
int (*local_infile_error)(void *, char *, uint))
{
if(mysql &&
local_infile_init &&
local_infile_read &&
local_infile_end &&
local_infile_error) {
mysql->options.local_infile_init= local_infile_init;
mysql->options.local_infile_read= local_infile_read;
mysql->options.local_infile_end= local_infile_end;
mysql->options.local_infile_error= local_infile_error;
return 0;
}
return 1;
}
void
mysql_set_local_infile_default(MYSQL *mysql)
{
mysql->options.local_infile_init= default_local_infile_init;
mysql->options.local_infile_read= default_local_infile_read;
mysql->options.local_infile_end= default_local_infile_end;
mysql->options.local_infile_error= default_local_infile_error;
} }
......
...@@ -1274,9 +1274,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, ...@@ -1274,9 +1274,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
I think mi_repair and mi_repair_by_sort should do the same I think mi_repair and mi_repair_by_sort should do the same
(according, e.g. to ha_myisam::repair), but as mi_repair doesn't (according, e.g. to ha_myisam::repair), but as mi_repair doesn't
touch key_map it cannot be used to T_CREATE_MISSING_KEYS. touch key_map it cannot be used to T_CREATE_MISSING_KEYS.
That is what the next line is for... (serg) That is what the next line is for
*/ */
if (param->testflag & T_CREATE_MISSING_KEYS)
share->state.key_map= ((((ulonglong) 1L << share->base.keys)-1) & share->state.key_map= ((((ulonglong) 1L << share->base.keys)-1) &
param->keys_in_use); param->keys_in_use);
......
...@@ -9,6 +9,21 @@ repair table t1 use_frm; ...@@ -9,6 +9,21 @@ repair table t1 use_frm;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 repair error The storage engine for the table doesn't support repair test.t1 repair error The storage engine for the table doesn't support repair
drop table t1; drop table t1;
create table t1(id int PRIMARY KEY, st varchar(10), KEY st_key(st));
insert into t1 values(1, "One");
alter table t1 disable keys;
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 id A 1 NULL NULL BTREE
t1 1 st_key 1 st A NULL NULL NULL YES BTREE disabled
repair table t1 extended;
Table Op Msg_type Msg_text
test.t1 repair status OK
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 id A 1 NULL NULL BTREE
t1 1 st_key 1 st A NULL NULL NULL YES BTREE disabled
drop table t1;
repair table t1 use_frm; repair table t1 use_frm;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 repair error Table 'test.t1' doesn't exist test.t1 repair error Table 'test.t1' doesn't exist
......
...@@ -1701,3 +1701,9 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1701,3 +1701,9 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1 2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1
drop table t1; drop table t1;
create table t1(id int);
create table t2(id int);
create table t3(flag int);
select (select * from t3 where id not null) from t1, t2;
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) from t1, t2' at line 1
drop table t1,t2,t3;
...@@ -36,8 +36,6 @@ a b ...@@ -36,8 +36,6 @@ a b
1 a 1 a
2 b 2 b
3 c 3 c
3 c
3 c
4 d 4 d
5 f 5 f
6 e 6 e
...@@ -48,8 +46,6 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select ...@@ -48,8 +46,6 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select
1 a 1 a
2 b 2 b
3 c 3 c
3 c
3 c
4 d 4 d
5 f 5 f
6 e 6 e
...@@ -920,5 +916,9 @@ select * from t1 UNION select * from t1 UNION ALL select * from t1; ...@@ -920,5 +916,9 @@ select * from t1 UNION select * from t1 UNION ALL select * from t1;
i i
1 1
1 1
1
drop table t1; drop table t1;
select 1 as a union all select 1 union all select 2 union select 1 union all select 2;
a
1
2
2
...@@ -12,6 +12,18 @@ alter table t1 ENGINE=HEAP; ...@@ -12,6 +12,18 @@ alter table t1 ENGINE=HEAP;
repair table t1 use_frm; repair table t1 use_frm;
drop table t1; drop table t1;
#
# disabled keys during repair
#
create table t1(id int PRIMARY KEY, st varchar(10), KEY st_key(st));
insert into t1 values(1, "One");
alter table t1 disable keys;
show keys from t1;
repair table t1 extended;
show keys from t1;
drop table t1;
# non-existent table # non-existent table
repair table t1 use_frm; repair table t1 use_frm;
......
...@@ -1105,3 +1105,13 @@ create table t1 (a int); ...@@ -1105,3 +1105,13 @@ create table t1 (a int);
insert into t1 values (1); insert into t1 values (1);
explain select benchmark(1000, (select a from t1 where a=sha(rand()))); explain select benchmark(1000, (select a from t1 where a=sha(rand())));
drop table t1; drop table t1;
#
# bug 3188
#
create table t1(id int);
create table t2(id int);
create table t3(flag int);
-- error 1064
select (select * from t3 where id not null) from t1, t2;
drop table t1,t2,t3;
...@@ -493,6 +493,7 @@ create table t1 (i int); ...@@ -493,6 +493,7 @@ create table t1 (i int);
insert into t1 values (1); insert into t1 values (1);
select * from t1 UNION select * from t1; select * from t1 UNION select * from t1;
select * from t1 UNION ALL select * from t1; select * from t1 UNION ALL select * from t1;
# The following should return 2 lines
select * from t1 UNION select * from t1 UNION ALL select * from t1; select * from t1 UNION select * from t1 UNION ALL select * from t1;
drop table t1; drop table t1;
select 1 as a union all select 1 union all select 2 union select 1 union all select 2;
...@@ -1358,12 +1358,15 @@ mysql_init(MYSQL *mysql) ...@@ -1358,12 +1358,15 @@ mysql_init(MYSQL *mysql)
Only enable LOAD DATA INFILE by default if configured with Only enable LOAD DATA INFILE by default if configured with
--enable-local-infile --enable-local-infile
*/ */
#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER) #if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER)
mysql->options.client_flag|= CLIENT_LOCAL_FILES; mysql->options.client_flag|= CLIENT_LOCAL_FILES;
#endif #endif
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
mysql->options.shared_memory_base_name= (char*) def_shared_memory_base_name; mysql->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
#endif #endif
mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION; mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION;
return mysql; return mysql;
} }
...@@ -2282,7 +2285,7 @@ get_info: ...@@ -2282,7 +2285,7 @@ get_info:
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
{ {
int error=send_file_to_server(mysql,(char*) pos); int error=handle_local_infile(mysql,(char*) pos);
if ((length=net_safe_read(mysql)) == packet_error || error) if ((length=net_safe_read(mysql)) == packet_error || error)
DBUG_RETURN(1); DBUG_RETURN(1);
goto get_info; /* Get info packet */ goto get_info; /* Get info packet */
......
...@@ -949,6 +949,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -949,6 +949,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
table_list, &where, table_list, &where,
0)) != not_found_field) 0)) != not_found_field)
{ {
if (!tmp)
return -1;
prev_subselect_item->used_tables_cache|= tmp->table->map; prev_subselect_item->used_tables_cache|= tmp->table->map;
prev_subselect_item->const_item_cache= 0; prev_subselect_item->const_item_cache= 0;
break; break;
......
...@@ -210,9 +210,6 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; ...@@ -210,9 +210,6 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
#define OPTION_RELAXED_UNIQUE_CHECKS (1L << 27) #define OPTION_RELAXED_UNIQUE_CHECKS (1L << 27)
#define SELECT_NO_UNLOCK (1L << 28) #define SELECT_NO_UNLOCK (1L << 28)
/* options for UNION set by the yacc parser (stored in unit->union_option) */
#define UNION_ALL 1
/* Bits for different SQL modes modes (including ANSI mode) */ /* Bits for different SQL modes modes (including ANSI mode) */
#define MODE_REAL_AS_FLOAT 1 #define MODE_REAL_AS_FLOAT 1
#define MODE_PIPES_AS_CONCAT 2 #define MODE_PIPES_AS_CONCAT 2
......
...@@ -138,7 +138,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, ...@@ -138,7 +138,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
*/ */
if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param, if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param,
unit->types, (ORDER*) 0, unit->types, (ORDER*) 0,
is_union && !unit->union_option, 1, is_union && unit->union_distinct, 1,
(first_select->options | thd->options | (first_select->options | thd->options |
TMP_TABLE_ALL_COLUMNS), TMP_TABLE_ALL_COLUMNS),
HA_POS_ERROR, HA_POS_ERROR,
......
...@@ -997,7 +997,7 @@ void st_select_lex_unit::init_query() ...@@ -997,7 +997,7 @@ void st_select_lex_unit::init_query()
global_parameters= first_select(); global_parameters= first_select();
select_limit_cnt= HA_POS_ERROR; select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0; offset_limit_cnt= 0;
union_option= 0; union_distinct= 0;
prepared= optimized= executed= 0; prepared= optimized= executed= 0;
item= 0; item= 0;
union_result= 0; union_result= 0;
...@@ -1572,7 +1572,7 @@ void st_select_lex_unit::print(String *str) ...@@ -1572,7 +1572,7 @@ void st_select_lex_unit::print(String *str)
if (sl != first_select()) if (sl != first_select())
{ {
str->append(" union ", 7); str->append(" union ", 7);
if (union_option & UNION_ALL) if (!union_distinct)
str->append("all ", 4); str->append("all ", 4);
} }
if (sl->braces) if (sl->braces)
......
...@@ -335,7 +335,7 @@ public: ...@@ -335,7 +335,7 @@ public:
/* fake SELECT_LEX for union processing */ /* fake SELECT_LEX for union processing */
st_select_lex *fake_select_lex; st_select_lex *fake_select_lex;
uint union_option; st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */
void init_query(); void init_query();
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
......
...@@ -210,7 +210,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -210,7 +210,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
union_result->tmp_table_param.field_count= types.elements; union_result->tmp_table_param.field_count= types.elements;
if (!(table= create_tmp_table(thd_arg, if (!(table= create_tmp_table(thd_arg,
&union_result->tmp_table_param, types, &union_result->tmp_table_param, types,
(ORDER*) 0, !union_option, 1, (ORDER*) 0, union_distinct, 1,
(first_select_in_union()->options | (first_select_in_union()->options |
thd_arg->options | thd_arg->options |
TMP_TABLE_ALL_COLUMNS), TMP_TABLE_ALL_COLUMNS),
...@@ -267,6 +267,8 @@ int st_select_lex_unit::exec() ...@@ -267,6 +267,8 @@ int st_select_lex_unit::exec()
item->reset(); item->reset();
table->file->delete_all_rows(); table->file->delete_all_rows();
} }
if (union_distinct) // for subselects
table->file->extra(HA_EXTRA_CHANGE_KEY_TO_UNIQUE);
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{ {
ha_rows records_at_start= 0; ha_rows records_at_start= 0;
...@@ -317,6 +319,8 @@ int st_select_lex_unit::exec() ...@@ -317,6 +319,8 @@ int st_select_lex_unit::exec()
{ {
records_at_start= table->file->records; records_at_start= table->file->records;
sl->join->exec(); sl->join->exec();
if (sl == union_distinct)
table->file->extra(HA_EXTRA_CHANGE_KEY_TO_DUP);
res= sl->join->error; res= sl->join->error;
offset_limit_cnt= sl->offset_limit; offset_limit_cnt= sl->offset_limit;
if (!res && union_result->flush()) if (!res && union_result->flush())
......
...@@ -611,7 +611,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -611,7 +611,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
udf_type if_exists opt_local opt_table_options table_options udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type
opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type opt_ignore_leaves fulltext_options spatial_type union_option
%type <ulong_num> %type <ulong_num>
ULONG_NUM raid_types merge_insert_types ULONG_NUM raid_types merge_insert_types
...@@ -718,7 +718,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -718,7 +718,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
table_to_table_list table_to_table opt_table_list opt_as table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild single_multi table_wild_list table_wild_one opt_wild
union_clause union_list union_option union_clause union_list
precision subselect_start opt_and charset precision subselect_start opt_and charset
subselect_end select_var_list select_var_list_init help opt_len subselect_end select_var_list select_var_list_init help opt_len
opt_extended_describe opt_extended_describe
...@@ -5589,6 +5589,9 @@ union_list: ...@@ -5589,6 +5589,9 @@ union_list:
YYABORT; YYABORT;
mysql_init_select(lex); mysql_init_select(lex);
lex->current_select->linkage=UNION_TYPE; lex->current_select->linkage=UNION_TYPE;
if ($2) /* UNION DISTINCT - remember position */
lex->current_select->master_unit()->union_distinct=
lex->current_select;
} }
select_init {} select_init {}
; ;
...@@ -5630,9 +5633,10 @@ order_or_limit: ...@@ -5630,9 +5633,10 @@ order_or_limit:
; ;
union_option: union_option:
/* empty */ {} /* empty */ { $$=1; }
| DISTINCT {} | DISTINCT { $$=1; }
| ALL {Select->master_unit()->union_option|= UNION_ALL;}; | ALL { $$=0; }
;
singlerow_subselect: singlerow_subselect:
subselect_start singlerow_subselect_init subselect_start singlerow_subselect_init
......
...@@ -8,10 +8,10 @@ typedef unsigned short uint16; ...@@ -8,10 +8,10 @@ typedef unsigned short uint16;
struct uca_item_st struct uca_item_st
{ {
uchar num; uchar num;
uint16 weight[4][8]; uint16 weight[4][9];
}; };
#if 1 #if 0
#define MY_UCA_NPAGES 1024 #define MY_UCA_NPAGES 1024
#define MY_UCA_NCHARS 64 #define MY_UCA_NCHARS 64
#define MY_UCA_CMASK 63 #define MY_UCA_CMASK 63
...@@ -30,8 +30,10 @@ int main(int ac, char **av) ...@@ -30,8 +30,10 @@ int main(int ac, char **av)
struct uca_item_st uca[64*1024]; struct uca_item_st uca[64*1024];
size_t code, page, w; size_t code, page, w;
int pagemaxlen[MY_UCA_NPAGES]; int pagemaxlen[MY_UCA_NPAGES];
int pageloaded[MY_UCA_NPAGES];
bzero(uca, sizeof(uca)); bzero(uca, sizeof(uca));
bzero(pageloaded, sizeof(pageloaded));
while (fgets(str,sizeof(str),stdin)) while (fgets(str,sizeof(str),stdin))
{ {
...@@ -69,7 +71,10 @@ int main(int ac, char **av) ...@@ -69,7 +71,10 @@ int main(int ac, char **av)
if (codenum>1) if (codenum>1)
{ {
/* Multi-character weight */ /* Multi-character weight,
i.e. contraction.
Not supported yet.
*/
continue; continue;
} }
...@@ -97,10 +102,13 @@ int main(int ac, char **av) ...@@ -97,10 +102,13 @@ int main(int ac, char **av)
s= endptr; s= endptr;
partnum++; partnum++;
} }
} }
/* Mark that a character from this page was loaded */
pageloaded[code >> MY_UCA_PSHIFT]++;
} }
/* Now set implicit weights */ /* Now set implicit weights */
for (code=0; code <= 0xFFFF; code++) for (code=0; code <= 0xFFFF; code++)
{ {
...@@ -156,6 +164,12 @@ int main(int ac, char **av) ...@@ -156,6 +164,12 @@ int main(int ac, char **av)
size_t nchars= 0; size_t nchars= 0;
size_t mchars; size_t mchars;
/*
Skip this page if no weights were loaded
*/
if (!pageloaded[page])
continue;
/* /*
Calculate maximum weight Calculate maximum weight
...@@ -176,8 +190,7 @@ int main(int ac, char **av) ...@@ -176,8 +190,7 @@ int main(int ac, char **av)
maxnum= maxnum < num ? num : maxnum; maxnum= maxnum < num ? num : maxnum;
} }
if (!maxnum) maxnum++;
maxnum=1;
switch (maxnum) switch (maxnum)
{ {
...@@ -191,13 +204,15 @@ int main(int ac, char **av) ...@@ -191,13 +204,15 @@ int main(int ac, char **av)
pagemaxlen[page]= maxnum; pagemaxlen[page]= maxnum;
printf("uint16 page%03Xdata[]= { /* %04X (%d weights per char) */\n",
page, page*MY_UCA_NCHARS, maxnum);
/* /*
Now print this page Now print this page
*/ */
printf("uint16 page%03Xdata[]= { /* %04X (%d weights per char) */\n",
page, page*MY_UCA_NCHARS, maxnum);
for (offs=0; offs < MY_UCA_NCHARS; offs++) for (offs=0; offs < MY_UCA_NCHARS; offs++)
{ {
uint16 weight[8]; uint16 weight[8];
...@@ -249,6 +264,9 @@ int main(int ac, char **av) ...@@ -249,6 +264,9 @@ int main(int ac, char **av)
printf("uint16 *ucaw[%d]={\n",MY_UCA_NPAGES); printf("uint16 *ucaw[%d]={\n",MY_UCA_NPAGES);
for (page=0; page < MY_UCA_NPAGES; page++) for (page=0; page < MY_UCA_NPAGES; page++)
{ {
if (!pageloaded[page])
printf("NULL %s%s",page<MY_UCA_NPAGES-1?",":"", (page+1) % 4 ? "":"\n");
else
printf("page%03Xdata%s%s",page,page<MY_UCA_NPAGES-1?",":"", (page+1) % 4 ? "":"\n"); printf("page%03Xdata%s%s",page,page<MY_UCA_NPAGES-1?",":"", (page+1) % 4 ? "":"\n");
} }
printf("};\n"); printf("};\n");
......
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