summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_parse.cc6
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_union.cc33
-rw-r--r--tests/client_test.c60
6 files changed, 87 insertions, 17 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 56857aaa632..2d71f145ded 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -564,7 +564,7 @@ TABLE_LIST * find_table_in_list(TABLE_LIST *table,
Find real table in given list.
SYNOPSIS
- find_table_in_list()
+ find_real_table_in_list()
table - pointer to table list
db_name - data base name
table_name - table name
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 914834a75bc..df7d487194a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1004,6 +1004,7 @@ void st_select_lex_unit::init_query()
table= 0;
fake_select_lex= 0;
cleaned= 0;
+ item_list.empty();
}
void st_select_lex::init_query()
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 73811dddf75..bfef9a01feb 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2378,8 +2378,10 @@ mysql_execute_command(THD *thd)
if (grant_option)
{
TABLE_LIST old_list,new_list;
- bzero((char*) &old_list, sizeof(old_list));
- bzero((char*) &new_list, sizeof(new_list)); // Safety
+ /*
+ we do not need initialize old_list and new_list because we will
+ come table[0] and table->next[0] there
+ */
old_list=table[0];
new_list=table->next[0];
old_list.next=new_list.next=0;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8011809d6ab..099dab8885b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2936,7 +2936,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
List<Item> field_list;
Item *item;
Protocol *protocol= thd->protocol;
- DBUG_ENTER("mysql_admin_table");
+ DBUG_ENTER("mysql_checksum_table");
field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
item->maybe_null= 1;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 3a27e606cff..6eb72b3ac3d 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -226,13 +226,23 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
thd_arg->lex->current_select= lex_select_save;
{
+ Statement *stmt= thd->current_statement;
+ Statement backup;
+ if (stmt)
+ thd->set_n_backup_item_arena(stmt, &backup);
Field **field;
for (field= table->field; *field; field++)
{
Item_field *item= new Item_field(*field);
if (!item || item_list.push_back(item))
+ {
+ if (stmt)
+ thd->restore_backup_item_arena(stmt, &backup);
DBUG_RETURN(-1);
+ }
}
+ if (stmt)
+ thd->restore_backup_item_arena(stmt, &backup);
}
}
else
@@ -431,7 +441,7 @@ int st_select_lex_unit::cleanup()
{
DBUG_RETURN(0);
}
- cleaned= 0;
+ cleaned= 1;
if (union_result)
{
@@ -465,16 +475,19 @@ void st_select_lex_unit::reinit_exec_mechanism()
{
prepared= optimized= executed= 0;
#ifndef DBUG_OFF
- List_iterator_fast<Item> it(item_list);
- Item_field *field;
- while ((field= (Item_field *)it++))
+ if (first_select()->next_select())
{
- /*
- we can't cleanup here, because it broke link to temporary table field,
- but have to drop fixed flag to allow next fix_field of this field
- during re-executing
- */
- field->fixed= 0;
+ List_iterator_fast<Item> it(item_list);
+ Item *field;
+ while ((field= it++))
+ {
+ /*
+ we can't cleanup here, because it broke link to temporary table field,
+ but have to drop fixed flag to allow next fix_field of this field
+ during re-executing
+ */
+ field->fixed= 0;
+ }
}
#endif
}
diff --git a/tests/client_test.c b/tests/client_test.c
index 31a53f6d81e..5aa48255a64 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -160,7 +160,10 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
MYSQL_STMT *STDCALL
mysql_simple_prepare(MYSQL *mysql, const char *query)
{
- return mysql_prepare(mysql, query, strlen(query));
+ MYSQL_STMT *stmt= mysql_stmt_init(mysql);
+ if (mysql_stmt_prepare(stmt, query, strlen(query)))
+ return 0;
+ return stmt;
}
@@ -8377,6 +8380,58 @@ static void test_subqueries_ref()
myquery(rc);
}
+
+static void test_union()
+{
+ MYSQL_STMT *stmt;
+ int rc;
+
+ myheader("test_union");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
+ myquery(rc);
+
+ rc= mysql_query(mysql,
+ "CREATE TABLE t1 "
+ "(id INTEGER NOT NULL PRIMARY KEY, "
+ " name VARCHAR(20) NOT NULL)");
+ myquery(rc);
+ rc= mysql_query(mysql,
+ "INSERT INTO t1 (id, name) VALUES "
+ "(2, 'Ja'), (3, 'Ede'), "
+ "(4, 'Haag'), (5, 'Kabul'), "
+ "(6, 'Almere'), (7, 'Utrecht'), "
+ "(8, 'Qandahar'), (9, 'Amsterdam'), "
+ "(10, 'Amersfoort'), (11, 'Constantine')");
+ myquery(rc);
+ rc= mysql_query(mysql,
+ "CREATE TABLE t2 "
+ "(id INTEGER NOT NULL PRIMARY KEY, "
+ " name VARCHAR(20) NOT NULL)");
+ myquery(rc);
+ rc= mysql_query(mysql,
+ "INSERT INTO t2 (id, name) VALUES "
+ "(4, 'Guam'), (5, 'Aruba'), "
+ "(6, 'Angola'), (7, 'Albania'), "
+ "(8, 'Anguilla'), (9, 'Argentina'), "
+ "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
+ "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql,
+ "SELECT t1.name FROM t1 UNION "
+ "SELECT t2.name FROM t2");
+ mystmt_init(stmt);
+
+ rc= mysql_stmt_execute(stmt);
+ mystmt(stmt,rc);
+ assert(20 == my_process_stmt_result(stmt));
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "DROP TABLE t1, t2");
+ myquery(rc);
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -8634,8 +8689,7 @@ int main(int argc, char **argv)
test_distinct(); /* distinct aggregate functions */
test_subqueries_ref(); /* outer reference in subqueries converted
Item_field -> Item_ref */
-
-
+ test_union(); /* test union with prepared statements */
end_time= time((time_t *)0);
total_time+= difftime(end_time, start_time);