Commit 66124a5e authored by serg@serg.mylan's avatar serg@serg.mylan

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

into serg.mylan:/usr/home/serg/Abk/mysql-4.1
parents 9336d010 6eaeebb5
...@@ -2050,7 +2050,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, ...@@ -2050,7 +2050,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
share->state.dellink= HA_OFFSET_ERROR; share->state.dellink= HA_OFFSET_ERROR;
share->state.split=(ha_rows) mrg->records; share->state.split=(ha_rows) mrg->records;
share->state.version=(ulong) time((time_t*) 0); share->state.version=(ulong) time((time_t*) 0);
if (share->state.key_map != (1ULL << share->base.keys) - 1) if (share->state.key_map != (ULL(1) << share->base.keys) - 1)
{ {
/* /*
Some indexes are disabled, cannot use current key_file_length value Some indexes are disabled, cannot use current key_file_length value
......
...@@ -413,14 +413,40 @@ deallocate prepare stmt; ...@@ -413,14 +413,40 @@ deallocate prepare stmt;
create table t1 (a int); create table t1 (a int);
insert into t1 values (1),(2),(3); insert into t1 values (1),(2),(3);
create table t2 select * from t1; create table t2 select * from t1;
PREPARE my_stmt FROM 'create table t2 select * from t1'; prepare stmt FROM 'create table t2 select * from t1';
drop table t2; drop table t2;
execute my_stmt; execute stmt;
drop table t2; drop table t2;
execute my_stmt; execute stmt;
execute my_stmt; execute stmt;
ERROR 42S01: Table 't2' already exists ERROR 42S01: Table 't2' already exists
drop table t2; drop table t2;
execute my_stmt; execute stmt;
drop table t1,t2; drop table t1,t2;
deallocate prepare my_stmt; deallocate prepare stmt;
create table t1 (a int);
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
prepare stmt from "select sql_calc_found_rows * from t1 limit 2";
execute stmt;
a
1
2
select found_rows();
found_rows()
10
execute stmt;
a
1
2
select found_rows();
found_rows()
10
execute stmt;
a
1
2
select found_rows();
found_rows()
10
deallocate prepare stmt;
drop table t1;
...@@ -176,17 +176,17 @@ a b ...@@ -176,17 +176,17 @@ a b
a b a b
1 7 1 7
2 7 2 7
3 8
4 8 4 8
3 8
explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using filesort 2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using filesort
3 UNION t4 ALL NULL NULL NULL NULL 3 Using where; Using filesort 3 UNION t4 ALL NULL NULL NULL NULL 3 Using where
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.b = (select test.t3.a AS `a` from test.t3 order by test.t3.a desc limit 1))) union (select test.t4.a AS `a`,test.t4.b AS `b` from test.t4 where (test.t4.b = (select (max(test.t2.a) * 4) AS `max(t2.a)*4` from test.t2)) order by test.t4.a) Note 1003 (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.b = (select test.t3.a AS `a` from test.t3 order by test.t3.a desc limit 1))) union (select test.t4.a AS `a`,test.t4.b AS `b` from test.t4 where (test.t4.b = (select (max(test.t2.a) * 4) AS `max(t2.a)*4` from test.t2)) order by a)
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
......
...@@ -422,14 +422,30 @@ deallocate prepare stmt; ...@@ -422,14 +422,30 @@ deallocate prepare stmt;
create table t1 (a int); create table t1 (a int);
insert into t1 values (1),(2),(3); insert into t1 values (1),(2),(3);
create table t2 select * from t1; create table t2 select * from t1;
PREPARE my_stmt FROM 'create table t2 select * from t1'; prepare stmt FROM 'create table t2 select * from t1';
drop table t2; drop table t2;
execute my_stmt; execute stmt;
drop table t2; drop table t2;
execute my_stmt; execute stmt;
--error 1050 --error 1050
execute my_stmt; execute stmt;
drop table t2; drop table t2;
execute my_stmt; execute stmt;
drop table t1,t2; drop table t1,t2;
deallocate prepare my_stmt; deallocate prepare stmt;
#
# Bug#6088 "FOUND_ROWS returns wrong values for prepared statements when
# LIMIT is used"
#
create table t1 (a int);
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
prepare stmt from "select sql_calc_found_rows * from t1 limit 2";
execute stmt;
select found_rows();
execute stmt;
select found_rows();
execute stmt;
select found_rows();
deallocate prepare stmt;
drop table t1;
...@@ -3591,7 +3591,7 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -3591,7 +3591,7 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list)
int mysql_revoke_all(THD *thd, List <LEX_USER> &list) int mysql_revoke_all(THD *thd, List <LEX_USER> &list)
{ {
uint counter; uint counter, revoked;
int result; int result;
ACL_DB *acl_db; ACL_DB *acl_db;
TABLE_LIST tables[4]; TABLE_LIST tables[4];
...@@ -3624,83 +3624,96 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -3624,83 +3624,96 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list)
} }
/* Remove db access privileges */ /* Remove db access privileges */
for (counter= 0 ; counter < acl_dbs.elements ; ) /*
Because acl_dbs and column_priv_hash shrink and may re-order
as privileges are removed, removal occurs in a repeated loop
until no more privileges are revoked.
*/
do
{ {
const char *user,*host; for (counter= 0, revoked= 0 ; counter < acl_dbs.elements ; )
acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*);
if (!(user=acl_db->user))
user= "";
if (!(host=acl_db->host.hostname))
host= "";
if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
{ {
if (!replace_db_table(tables[1].table, acl_db->db, *lex_user, ~0, 1)) const char *user,*host;
{
/* acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*);
Don't increment counter as replace_db_table deleted the if (!(user=acl_db->user))
current element in acl_db's and shifted the higher elements down user= "";
*/ if (!(host=acl_db->host.hostname))
continue; host= "";
}
result= -1; // Something went wrong if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
{
if (!replace_db_table(tables[1].table, acl_db->db, *lex_user, ~0, 1))
{
/*
Don't increment counter as replace_db_table deleted the
current element in acl_dbs.
*/
revoked= 1;
continue;
}
result= -1; // Something went wrong
}
counter++;
} }
counter++; } while (revoked);
}
/* Remove column access */ /* Remove column access */
for (counter= 0 ; counter < column_priv_hash.records ; ) do
{ {
const char *user,*host; for (counter= 0, revoked= 0 ; counter < column_priv_hash.records ; )
GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash,
counter);
if (!(user=grant_table->user))
user= "";
if (!(host=grant_table->host))
host= "";
if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
{ {
if (replace_table_table(thd,grant_table,tables[2].table,*lex_user, const char *user,*host;
grant_table->db, GRANT_TABLE *grant_table= (GRANT_TABLE*)hash_element(&column_priv_hash,
grant_table->tname, counter);
~0, 0, 1)) if (!(user=grant_table->user))
{ user= "";
result= -1; if (!(host=grant_table->host))
continue; host= "";
}
else if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
{ {
if (!grant_table->cols) if (replace_table_table(thd,grant_table,tables[2].table,*lex_user,
continue; grant_table->db,
List<LEX_COLUMN> columns; grant_table->tname,
if (replace_column_table(grant_table,tables[3].table, *lex_user, ~0, 0, 1))
columns, {
grant_table->db, result= -1;
grant_table->tname, }
~0, 1)) else
result= -1; {
/* if (!grant_table->cols)
Safer to do continue here as replace_table_table changed {
column_priv_hash and we want to test the current element revoked= 1;
*/ continue;
continue; }
List<LEX_COLUMN> columns;
if (!replace_column_table(grant_table,tables[3].table, *lex_user,
columns,
grant_table->db,
grant_table->tname,
~0, 1))
{
revoked= 1;
continue;
}
result= -1;
}
} }
counter++;
} }
counter++; } while (revoked);
}
} }
VOID(pthread_mutex_unlock(&acl_cache->lock)); VOID(pthread_mutex_unlock(&acl_cache->lock));
rw_unlock(&LOCK_grant); rw_unlock(&LOCK_grant);
close_thread_tables(thd); close_thread_tables(thd);
if (result) if (result)
my_error(ER_REVOKE_GRANTS, MYF(0)); my_error(ER_REVOKE_GRANTS, MYF(0));
DBUG_RETURN(result); DBUG_RETURN(result);
} }
......
...@@ -1563,6 +1563,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1563,6 +1563,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_CREATE_DB: // QQ: To be removed case COM_CREATE_DB: // QQ: To be removed
{ {
char *db=thd->strdup(packet), *alias; char *db=thd->strdup(packet), *alias;
HA_CREATE_INFO create_info;
statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status);
// null test to handle EOM // null test to handle EOM
...@@ -1574,8 +1575,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1574,8 +1575,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (check_access(thd,CREATE_ACL,db,0,1,0)) if (check_access(thd,CREATE_ACL,db,0,1,0))
break; break;
mysql_log.write(thd,command,packet); mysql_log.write(thd,command,packet);
bzero(&create_info, sizeof(create_info));
if (mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), if (mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db),
0, 0) < 0) &create_info, 0) < 0)
send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0);
break; break;
} }
......
...@@ -147,6 +147,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -147,6 +147,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
SELECT_LEX *lex_select_save= thd_arg->lex->current_select; SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
SELECT_LEX *sl, *first_select; SELECT_LEX *sl, *first_select;
select_result *tmp_result; select_result *tmp_result;
bool is_union;
DBUG_ENTER("st_select_lex_unit::prepare"); DBUG_ENTER("st_select_lex_unit::prepare");
describe= test(additional_options & SELECT_DESCRIBE); describe= test(additional_options & SELECT_DESCRIBE);
...@@ -183,10 +184,11 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -183,10 +184,11 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
thd_arg->lex->current_select= sl= first_select= first_select_in_union(); thd_arg->lex->current_select= sl= first_select= first_select_in_union();
found_rows_for_union= first_select->options & OPTION_FOUND_ROWS; found_rows_for_union= first_select->options & OPTION_FOUND_ROWS;
is_union= test(first_select->next_select());
/* Global option */ /* Global option */
if (first_select->next_select()) if (is_union)
{ {
if (!(tmp_result= union_result= new select_union(0))) if (!(tmp_result= union_result= new select_union(0)))
goto err; goto err;
...@@ -195,14 +197,11 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -195,14 +197,11 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
tmp_result= sel_result; tmp_result= sel_result;
} }
else else
{
tmp_result= sel_result; tmp_result= sel_result;
// single select should be processed like select in p[arantses
first_select->braces= 1;
}
for (;sl; sl= sl->next_select()) for (;sl; sl= sl->next_select())
{ {
bool can_skip_order_by;
sl->options|= SELECT_NO_UNLOCK; sl->options|= SELECT_NO_UNLOCK;
JOIN *join= new JOIN(thd_arg, sl->item_list, JOIN *join= new JOIN(thd_arg, sl->item_list,
sl->options | thd_arg->options | additional_options, sl->options | thd_arg->options | additional_options,
...@@ -217,14 +216,17 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -217,14 +216,17 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
select_limit_cnt= HA_POS_ERROR; // no limit select_limit_cnt= HA_POS_ERROR; // no limit
if (select_limit_cnt == HA_POS_ERROR || sl->braces) if (select_limit_cnt == HA_POS_ERROR || sl->braces)
sl->options&= ~OPTION_FOUND_ROWS; sl->options&= ~OPTION_FOUND_ROWS;
can_skip_order_by= is_union &&
(!sl->braces || select_limit_cnt == HA_POS_ERROR);
res= join->prepare(&sl->ref_pointer_array, res= join->prepare(&sl->ref_pointer_array,
(TABLE_LIST*) sl->table_list.first, sl->with_wild, (TABLE_LIST*) sl->table_list.first, sl->with_wild,
sl->where, sl->where,
((sl->braces) ? sl->order_list.elements : 0) + (can_skip_order_by ? 0 : sl->order_list.elements) +
sl->group_list.elements, sl->group_list.elements,
(sl->braces) ? can_skip_order_by ?
(ORDER *)sl->order_list.first : (ORDER *) 0, (ORDER*) 0 : (ORDER *)sl->order_list.first,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
...@@ -264,10 +266,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -264,10 +266,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
} }
} }
if (first_select->next_select()) if (is_union)
{ {
/* This is not a single select */
/* /*
Check that it was possible to aggregate Check that it was possible to aggregate
all collations together for UNION. all collations together for UNION.
...@@ -364,8 +364,6 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -364,8 +364,6 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
} }
} }
} }
else
first_select->braces= 0; // remove our changes
thd_arg->lex->current_select= lex_select_save; thd_arg->lex->current_select= lex_select_save;
......
...@@ -10688,6 +10688,31 @@ static void test_bug6046() ...@@ -10688,6 +10688,31 @@ static void test_bug6046()
} }
/*
Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
should not crash server and should not hang in case of errors.
Since those functions can't be seen in modern API (unless client library
was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
*/
static void test_bug6081()
{
int rc;
myheader("test_bug6081");
rc= simple_command(mysql, COM_DROP_DB, current_db,
(ulong)strlen(current_db), 0);
myquery(rc);
rc= simple_command(mysql, COM_DROP_DB, current_db,
(ulong)strlen(current_db), 0);
myquery_r(rc);
rc= simple_command(mysql, COM_CREATE_DB, current_db,
(ulong)strlen(current_db), 0);
myquery(rc);
rc= simple_command(mysql, COM_CREATE_DB, current_db,
(ulong)strlen(current_db), 0);
myquery_r(rc);
}
/* /*
...@@ -11004,6 +11029,7 @@ int main(int argc, char **argv) ...@@ -11004,6 +11029,7 @@ int main(int argc, char **argv)
test_bug6058(); /* check support for 0000-00-00 dates */ test_bug6058(); /* check support for 0000-00-00 dates */
test_bug6059(); /* correct metadata for SELECT ... INTO OUTFILE */ test_bug6059(); /* correct metadata for SELECT ... INTO OUTFILE */
test_bug6046(); /* NATURAL JOIN transformation works in PS */ test_bug6046(); /* NATURAL JOIN transformation works in PS */
test_bug6081(); /* test of mysql_create_db()/mysql_rm_db() */
/* /*
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
......
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