mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
reverting table list to be able to use it in next PS call (BUG#2811)
This commit is contained in:
@ -1864,7 +1864,6 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
#endif /* !HAVE_REPLICATION */
|
#endif /* !HAVE_REPLICATION */
|
||||||
if (&lex->select_lex != lex->all_selects_list &&
|
if (&lex->select_lex != lex->all_selects_list &&
|
||||||
lex->sql_command != SQLCOM_CREATE_TABLE &&
|
|
||||||
lex->unit.create_total_list(thd, lex, &tables))
|
lex->unit.create_total_list(thd, lex, &tables))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
@ -2166,12 +2165,16 @@ mysql_execute_command(THD *thd)
|
|||||||
{
|
{
|
||||||
/* Skip first table, which is the table we are creating */
|
/* Skip first table, which is the table we are creating */
|
||||||
TABLE_LIST *create_table= tables;
|
TABLE_LIST *create_table= tables;
|
||||||
|
TABLE_LIST *create_table_local=
|
||||||
|
(TABLE_LIST*)lex->select_lex.table_list.first;
|
||||||
|
// exclude from global table list
|
||||||
tables= tables->next;
|
tables= tables->next;
|
||||||
lex->select_lex.table_list.first= (byte*) (tables);
|
// and from local list if it is not the same
|
||||||
|
if (&lex->select_lex != lex->all_selects_list)
|
||||||
|
lex->select_lex.table_list.first= (gptr)create_table_local->next;
|
||||||
|
else
|
||||||
|
lex->select_lex.table_list.first= (gptr)tables;
|
||||||
create_table->next= 0;
|
create_table->next= 0;
|
||||||
if (&lex->select_lex != lex->all_selects_list &&
|
|
||||||
lex->unit.create_total_list(thd, lex, &tables))
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
|
|
||||||
ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
|
ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
|
||||||
CREATE_TMP_ACL : CREATE_ACL);
|
CREATE_TMP_ACL : CREATE_ACL);
|
||||||
@ -2181,10 +2184,10 @@ mysql_execute_command(THD *thd)
|
|||||||
check_merge_table_access(thd, create_table->db,
|
check_merge_table_access(thd, create_table->db,
|
||||||
(TABLE_LIST *)
|
(TABLE_LIST *)
|
||||||
lex->create_info.merge_list.first))
|
lex->create_info.merge_list.first))
|
||||||
goto error; /* purecov: inspected */
|
goto create_eror; /* purecov: inspected */
|
||||||
if (grant_option && want_priv != CREATE_TMP_ACL &&
|
if (grant_option && want_priv != CREATE_TMP_ACL &&
|
||||||
check_grant(thd, want_priv, create_table,0,0))
|
check_grant(thd, want_priv, create_table,0,0))
|
||||||
goto error;
|
goto create_eror;
|
||||||
#ifndef HAVE_READLINK
|
#ifndef HAVE_READLINK
|
||||||
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
|
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
|
||||||
#else
|
#else
|
||||||
@ -2195,7 +2198,7 @@ mysql_execute_command(THD *thd)
|
|||||||
create_table->real_name))
|
create_table->real_name))
|
||||||
{
|
{
|
||||||
res=-1;
|
res=-1;
|
||||||
break;
|
goto unsent_create_error;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
@ -2220,10 +2223,10 @@ mysql_execute_command(THD *thd)
|
|||||||
create_table->real_name))
|
create_table->real_name))
|
||||||
{
|
{
|
||||||
net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name);
|
net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name);
|
||||||
DBUG_VOID_RETURN;
|
goto create_eror;
|
||||||
}
|
}
|
||||||
if (tables && check_table_access(thd, SELECT_ACL, tables,0))
|
if (tables && check_table_access(thd, SELECT_ACL, tables,0))
|
||||||
goto error; // Error message is given
|
goto create_eror; // Error message is given
|
||||||
select_lex->options|= SELECT_NO_UNLOCK;
|
select_lex->options|= SELECT_NO_UNLOCK;
|
||||||
unit->offset_limit_cnt= select_lex->offset_limit;
|
unit->offset_limit_cnt= select_lex->offset_limit;
|
||||||
unit->select_limit_cnt= select_lex->select_limit+
|
unit->select_limit_cnt= select_lex->select_limit+
|
||||||
@ -2258,6 +2261,35 @@ mysql_execute_command(THD *thd)
|
|||||||
if (!res)
|
if (!res)
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
}
|
}
|
||||||
|
// put tables back for PS rexecuting
|
||||||
|
create_table->next= tables;
|
||||||
|
tables= create_table;
|
||||||
|
if (&lex->select_lex != lex->all_selects_list)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
we do not touch local table 'next' field => we need just
|
||||||
|
put the table in the list
|
||||||
|
*/
|
||||||
|
lex->select_lex.table_list.first= (gptr) create_table_local;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lex->select_lex.table_list.first= (gptr) tables;
|
||||||
|
break;
|
||||||
|
|
||||||
|
create_eror:
|
||||||
|
res= 1; //error reported
|
||||||
|
unsent_create_error:
|
||||||
|
// put tables back for PS rexecuting
|
||||||
|
create_table->next= tables;
|
||||||
|
tables= create_table;
|
||||||
|
if (&lex->select_lex != lex->all_selects_list)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
we do not touch local table 'next' field => we need just
|
||||||
|
put the table in the list
|
||||||
|
*/
|
||||||
|
lex->select_lex.table_list.first= (gptr) create_table_local;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_CREATE_INDEX:
|
case SQLCOM_CREATE_INDEX:
|
||||||
@ -2617,13 +2649,8 @@ mysql_execute_command(THD *thd)
|
|||||||
{
|
{
|
||||||
ulong privilege= (lex->duplicates == DUP_REPLACE ?
|
ulong privilege= (lex->duplicates == DUP_REPLACE ?
|
||||||
INSERT_ACL | DELETE_ACL : INSERT_ACL);
|
INSERT_ACL | DELETE_ACL : INSERT_ACL);
|
||||||
TABLE_LIST *save_next=tables->next;
|
|
||||||
tables->next=0;
|
|
||||||
if (check_one_table_access(thd, privilege, tables, 0))
|
if (check_one_table_access(thd, privilege, tables, 0))
|
||||||
goto error;
|
goto error;
|
||||||
tables->next=save_next;
|
|
||||||
if (check_table_access(thd, SELECT_ACL, save_next, 0))
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix lock for first table */
|
/* Fix lock for first table */
|
||||||
@ -3479,7 +3506,10 @@ static int check_one_table_access(THD *thd, ulong privilege,
|
|||||||
TABLE_LIST *subselects_tables= tables->next;
|
TABLE_LIST *subselects_tables= tables->next;
|
||||||
tables->next= 0;
|
tables->next= 0;
|
||||||
if (grant_option && check_grant(thd, privilege, tables, 0, 0))
|
if (grant_option && check_grant(thd, privilege, tables, 0, 0))
|
||||||
|
{
|
||||||
|
tables->next= subselects_tables;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// check rights on tables of subselect (if exists)
|
// check rights on tables of subselect (if exists)
|
||||||
if (subselects_tables)
|
if (subselects_tables)
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
||||||
bool skip_error);
|
bool skip_error);
|
||||||
|
|
||||||
|
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Every second entry in the table_list is the original name and every
|
Every second entry in the table_list is the original name and every
|
||||||
second entry is the new name.
|
second entry is the new name.
|
||||||
@ -56,17 +58,10 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
|
|||||||
if ((ren_table=rename_tables(thd,table_list,0)))
|
if ((ren_table=rename_tables(thd,table_list,0)))
|
||||||
{
|
{
|
||||||
/* Rename didn't succeed; rename back the tables in reverse order */
|
/* Rename didn't succeed; rename back the tables in reverse order */
|
||||||
TABLE_LIST *prev=0,*table;
|
TABLE_LIST *table;
|
||||||
/* Reverse the table list */
|
|
||||||
|
|
||||||
while (table_list)
|
/* Reverse the table list */
|
||||||
{
|
table_list= reverse_table_list(table_list);
|
||||||
TABLE_LIST *next=table_list->next;
|
|
||||||
table_list->next=prev;
|
|
||||||
prev=table_list;
|
|
||||||
table_list=next;
|
|
||||||
}
|
|
||||||
table_list=prev;
|
|
||||||
|
|
||||||
/* Find the last renamed table */
|
/* Find the last renamed table */
|
||||||
for (table=table_list ;
|
for (table=table_list ;
|
||||||
@ -75,6 +70,10 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
|
|||||||
table=table->next->next; // Skip error table
|
table=table->next->next; // Skip error table
|
||||||
/* Revert to old names */
|
/* Revert to old names */
|
||||||
rename_tables(thd, table, 1);
|
rename_tables(thd, table, 1);
|
||||||
|
|
||||||
|
/* Revert the table list (for prepared statements) */
|
||||||
|
table_list= reverse_table_list(table_list);
|
||||||
|
|
||||||
error= 1;
|
error= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +99,31 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
reverse table list
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
reverse_table_list()
|
||||||
|
table_list pointer to table _list
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
pointer to new (reversed) list
|
||||||
|
*/
|
||||||
|
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
|
||||||
|
{
|
||||||
|
TABLE_LIST *prev= 0;
|
||||||
|
|
||||||
|
while (table_list)
|
||||||
|
{
|
||||||
|
TABLE_LIST *next= table_list->next;
|
||||||
|
table_list->next= prev;
|
||||||
|
prev= table_list;
|
||||||
|
table_list= next;
|
||||||
|
}
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Rename all tables in list; Return pointer to wrong entry if something goes
|
Rename all tables in list; Return pointer to wrong entry if something goes
|
||||||
wrong. Note that the table_list may be empty!
|
wrong. Note that the table_list may be empty!
|
||||||
|
@ -8495,7 +8495,7 @@ static void test_bug3117()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void jest_join()
|
static void test_join()
|
||||||
{
|
{
|
||||||
MYSQL_STMT *stmt;
|
MYSQL_STMT *stmt;
|
||||||
int rc, i, j;
|
int rc, i, j;
|
||||||
@ -8509,7 +8509,7 @@ static void jest_join()
|
|||||||
"SELECT * FROM t2 natural right join t1",
|
"SELECT * FROM t2 natural right join t1",
|
||||||
"SELECT * FROM t2 right join t1 using(a)"};
|
"SELECT * FROM t2 right join t1 using(a)"};
|
||||||
|
|
||||||
myheader("jest_join");
|
myheader("test_join");
|
||||||
|
|
||||||
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2");
|
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2");
|
||||||
myquery(rc);
|
myquery(rc);
|
||||||
@ -8526,6 +8526,7 @@ static void jest_join()
|
|||||||
|
|
||||||
rc= mysql_query(mysql,
|
rc= mysql_query(mysql,
|
||||||
"insert into t2 values (1,1), (2, 2), (3,3), (4,4), (5,5);");
|
"insert into t2 values (1,1), (2, 2), (3,3), (4,4), (5,5);");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
for (j= 0; j < 9; j++)
|
for (j= 0; j < 9; j++)
|
||||||
{
|
{
|
||||||
@ -8591,6 +8592,83 @@ static void test_selecttmp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_create_drop()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt_create, *stmt_drop;
|
||||||
|
char *query;
|
||||||
|
int rc, i;
|
||||||
|
myheader("test_table_manipulation");
|
||||||
|
|
||||||
|
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
query= (char*)"create table t1 (a int)";
|
||||||
|
stmt_create= mysql_prepare(mysql, query, strlen(query));
|
||||||
|
mystmt_init(stmt_create);
|
||||||
|
|
||||||
|
query= (char*)"drop table t1";
|
||||||
|
stmt_drop= mysql_prepare(mysql, query, strlen(query));
|
||||||
|
mystmt_init(stmt_drop);
|
||||||
|
|
||||||
|
for (i= 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
rc= mysql_execute(stmt_create);
|
||||||
|
mystmt(stmt_create, rc);
|
||||||
|
fprintf(stdout, "created %i\n", i);
|
||||||
|
rc= mysql_execute(stmt_drop);
|
||||||
|
mystmt(stmt_drop, rc);
|
||||||
|
fprintf(stdout, "droped %i\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_stmt_close(stmt_create);
|
||||||
|
mysql_stmt_close(stmt_drop);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_rename()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
const char *query= "rename table t1 to t2, t3 to t4";
|
||||||
|
int rc;
|
||||||
|
myheader("test_table_manipulation");
|
||||||
|
|
||||||
|
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,t4");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt= mysql_prepare(mysql, query, strlen(query));
|
||||||
|
mystmt_init(stmt);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,"create table t1 (a int)");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_execute(stmt);
|
||||||
|
mystmt_r(stmt, rc);
|
||||||
|
fprintf(stdout, "rename without t3\n");
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,"create table t3 (a int)");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_execute(stmt);
|
||||||
|
mystmt(stmt, rc);
|
||||||
|
fprintf(stdout, "rename with t3\n");
|
||||||
|
|
||||||
|
rc= mysql_execute(stmt);
|
||||||
|
mystmt_r(stmt, rc);
|
||||||
|
fprintf(stdout, "rename renamed\n");
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,"rename table t2 to t1, t4 to t3");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_execute(stmt);
|
||||||
|
mystmt(stmt, rc);
|
||||||
|
fprintf(stdout, "rename reverted\n");
|
||||||
|
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE t2,t4");
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
@ -8850,9 +8928,10 @@ int main(int argc, char **argv)
|
|||||||
Item_field -> Item_ref */
|
Item_field -> Item_ref */
|
||||||
test_union(); /* test union with prepared statements */
|
test_union(); /* test union with prepared statements */
|
||||||
test_bug3117(); /* BUG#3117: LAST_INSERT_ID() */
|
test_bug3117(); /* BUG#3117: LAST_INSERT_ID() */
|
||||||
jest_join(); /* different kinds of join, BUG#2794 */
|
test_join(); /* different kinds of join, BUG#2794 */
|
||||||
test_selecttmp(); /* temporary table used in select execution */
|
test_selecttmp(); /* temporary table used in select execution */
|
||||||
|
test_create_drop(); /* some table manipulation BUG#2811 */
|
||||||
|
test_rename(); /* rename test */
|
||||||
|
|
||||||
end_time= time((time_t *)0);
|
end_time= time((time_t *)0);
|
||||||
total_time+= difftime(end_time, start_time);
|
total_time+= difftime(end_time, start_time);
|
||||||
|
Reference in New Issue
Block a user