Changes for the furtherment of UNIONS

parent dcac1079
...@@ -481,12 +481,13 @@ class select_insert :public select_result { ...@@ -481,12 +481,13 @@ class select_insert :public select_result {
uint save_time_stamp; uint save_time_stamp;
ulonglong last_insert_id; ulonglong last_insert_id;
COPY_INFO info; COPY_INFO info;
bool unions;
select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic) select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic, bool u=false)
:table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0) :table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0)
{ {
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
info.handle_duplicates=duplic; info.handle_duplicates=duplic; unions = u;
} }
~select_insert(); ~select_insert();
int prepare(List<Item> &list); int prepare(List<Item> &list);
...@@ -511,8 +512,8 @@ class select_create: public select_insert { ...@@ -511,8 +512,8 @@ class select_create: public select_insert {
HA_CREATE_INFO *create_info_par, HA_CREATE_INFO *create_info_par,
List<create_field> &fields_par, List<create_field> &fields_par,
List<Key> &keys_par, List<Key> &keys_par,
List<Item> &select_fields,enum_duplicates duplic) List<Item> &select_fields,enum_duplicates duplic, bool u=false)
:select_insert (NULL, &select_fields, duplic), db(db_name), :select_insert (NULL, &select_fields, duplic, u), db(db_name),
name(table_name), extra_fields(&fields_par),keys(&keys_par), name(table_name), extra_fields(&fields_par),keys(&keys_par),
create_info(create_info_par), create_info(create_info_par),
lock(0) lock(0)
......
...@@ -1318,7 +1318,8 @@ bool select_insert::send_eof() ...@@ -1318,7 +1318,8 @@ bool select_insert::send_eof()
thd->cuted_fields); thd->cuted_fields);
if (last_insert_id) if (last_insert_id)
thd->insert_id(last_insert_id); // For update log thd->insert_id(last_insert_id); // For update log
::send_ok(&thd->net,info.copied,last_insert_id,buff); if (!unions)
::send_ok(&thd->net,info.copied,last_insert_id,buff);
mysql_update_log.write(thd,thd->query,thd->query_length); mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
...@@ -1400,7 +1401,9 @@ bool select_create::send_eof() ...@@ -1400,7 +1401,9 @@ bool select_create::send_eof()
mysql_unlock_tables(thd, lock); mysql_unlock_tables(thd, lock);
if (!table->tmp_table) if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table); hash_delete(&open_cache,(byte*) table);
lock=0; table=0; lock=0;
if (!unions)
table=0;
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
} }
return tmp; return tmp;
......
...@@ -1754,7 +1754,15 @@ mysql_execute_command(void) ...@@ -1754,7 +1754,15 @@ mysql_execute_command(void)
break; break;
} }
if (!(res=open_and_lock_tables(thd,(TABLE_LIST *)total->first))) if (!(res=open_and_lock_tables(thd,(TABLE_LIST *)total->first)))
{
/* Fix tables--to-be-unioned-from list to point at opened tables */
for (SELECT_LEX *sl=&lex->select_lex;sl;sl=sl->next)
{
for (TABLE_LIST *cursor=(TABLE_LIST *)sl->table_list.first;cursor;cursor=cursor->next)
cursor->table= ((TABLE_LIST*) cursor->table)->table;
}
res=mysql_union(thd,lex, select_lex->select_number+1); res=mysql_union(thd,lex, select_lex->select_number+1);
}
close_thread_tables(thd); close_thread_tables(thd);
break; break;
} }
...@@ -2894,11 +2902,12 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, ...@@ -2894,11 +2902,12 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables) static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables)
{ {
SELECT_LEX *sl; const char *current_db=thd->db ? thd->db : ""; SELECT_LEX *sl; const char *current_db=thd->db ? thd->db : "";
TABLE_LIST *ptr;
for (sl=&lex->select_lex;sl;sl=sl->next) for (sl=&lex->select_lex;sl;sl=sl->next)
{ {
if ((lex->sql_command == SQLCOM_UNION_SELECT) && (sl->order_list.first != (byte *)NULL) && (sl->next != (st_select_lex *)NULL)) if ((lex->sql_command == SQLCOM_UNION_SELECT) && (sl->order_list.first != (byte *)NULL) && (sl->next != (st_select_lex *)NULL))
{ {
net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); // correct error message will come here; only last SELECt can have ORDER BY net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); // correct error message will come here; only last SELECT can have ORDER BY
return -1; return -1;
} }
if (sl->table_list.first == (byte *)NULL) continue; if (sl->table_list.first == (byte *)NULL) continue;
...@@ -2919,7 +2928,15 @@ static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables) ...@@ -2919,7 +2928,15 @@ static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables)
aux->lock_type= lex->lock_option; aux->lock_type= lex->lock_option;
if (!tables->next) if (!tables->next)
tables->next= (byte**) &tables->first; tables->next= (byte**) &tables->first;
link_in_list(tables,(byte*)aux,(byte**) &aux->next); if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
return 1;
ptr->db= aux->db; ptr->real_name=aux->real_name;
ptr->name=aux->name; ptr->lock_type=aux->lock_type;
ptr->updating=aux->updating;
ptr->use_index=aux->use_index;
ptr->ignore_index=aux->use_index;
aux->table=(TABLE *)ptr;
link_in_list(tables,(byte*)ptr,(byte**) &ptr->next);
} }
} }
} }
......
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
int mysql_union(THD *thd,LEX *lex,uint no_of_selects) int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
{ {
SELECT_LEX *sl, *for_order=&lex->select_lex; uint no=0; int res=0; SELECT_LEX *sl, *for_order=&lex->select_lex; uint no=0; int res=0;
List<Item> fields; TABLE *table=(TABLE *)NULL; TABLE_LIST *resulting=(TABLE_LIST *)NULL; select_create *create_result;
List<Item> fields; TABLE *table=(TABLE *)NULL; TABLE_LIST *resulting=(TABLE_LIST *)NULL;
for (;for_order->next;for_order=for_order->next); for (;for_order->next;for_order=for_order->next);
ORDER *some_order = (ORDER *)for_order->order_list.first; ORDER *some_order = (ORDER *)for_order->order_list.first;
for (sl=&lex->select_lex;sl;sl=sl->next, no++) for (sl=&lex->select_lex;sl;sl=sl->next, no++)
...@@ -37,102 +38,110 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) ...@@ -37,102 +38,110 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
TABLE_LIST *tables=(TABLE_LIST*) sl->table_list.first; TABLE_LIST *tables=(TABLE_LIST*) sl->table_list.first;
if (!no) // First we do CREATE from SELECT if (!no) // First we do CREATE from SELECT
{ {
select_create *result;
lex->create_info.options=HA_LEX_CREATE_TMP_TABLE; lex->create_info.options=HA_LEX_CREATE_TMP_TABLE;
if ((result=new select_create(tables->db ? tables->db : thd->db, lex->create_info.db_type=DB_TYPE_MYISAM;
NULL, &lex->create_info, lex->create_info.row_type = ROW_TYPE_DEFAULT;
lex->create_info.avg_row_length = 0;
lex->create_info.max_rows=INT_MAX; lex->create_info.min_rows=0;
lex->create_info.comment=lex->create_info.password=NullS;
lex->create_info.data_file_name=lex->create_info.index_file_name=NullS;
lex->create_info.raid_type=lex->create_info.raid_chunks=0;
lex->create_info.raid_chunksize=0;
lex->create_info.if_not_exists=false;
lex->create_info.used_fields=0;
if ((create_result=new select_create(tables->db ? tables->db : thd->db,
"ZVEK", &lex->create_info,
lex->create_list, lex->create_list,
lex->key_list, lex->key_list,
sl->item_list,DUP_IGNORE))) sl->item_list,DUP_IGNORE,true)))
{ {
res=mysql_select(thd,tables,sl->item_list, res=mysql_select(thd,tables,sl->item_list,
sl->where, sl->where,
sl->ftfunc_list, sl->ftfunc_list,
(ORDER*) NULL, (ORDER*) NULL,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, sl->having,
(ORDER*) some_order, (ORDER*) some_order,
sl->options | thd->options, sl->options | thd->options,
result); create_result);
if (res) if (res)
{ {
result->abort(); create_result->abort();
delete result; delete create_result;
return res; return res;
} }
table=result->table; table=create_result->table;
List_iterator<Item> it(*(result->fields)); List_iterator<Item> it(*(create_result->fields));
Item *item; Item *item;
while ((item= it++)) while ((item= it++))
fields.push_back(item); fields.push_back(item);
delete result; if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
if (!reopen_table(table)) return 1; return 1;
if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))) resulting->db=tables->db ? tables->db : thd->db;
return 1; resulting->real_name=table->real_name;
resulting->db=tables->db ? tables->db : thd->db; resulting->name=table->table_name;
resulting->real_name=table->real_name; resulting->table=table;
resulting->name=table->table_name;
resulting->table=table;
} }
else else
return -1; return -1;
} }
else // Then we do INSERT from SELECT else // Then we do INSERT from SELECT
{ {
select_result *result; select_result *result;
if ((result=new select_insert(table, &fields, DUP_IGNORE))) if ((result=new select_insert(table, &fields, DUP_IGNORE, true)))
{ {
res=mysql_select(thd,tables,sl->item_list, res=mysql_select(thd,tables,sl->item_list,
sl->where, sl->where,
sl->ftfunc_list, sl->ftfunc_list,
(ORDER*) some_order, (ORDER*) some_order,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
sl->options | thd->options, sl->options | thd->options,
result); result);
delete result; delete result;
if (res) return 1; if (res)
{
delete create_result;
return 1;
}
} }
else else
return -1; {
delete create_result;
return -1;
}
} }
} }
select_result *result; select_result *result;
List<Item> item_list; List<Item> item_list;
List<Item_func_match> ftfunc_list; List<Item_func_match> ftfunc_list;
ftfunc_list.empty(); ftfunc_list.empty();
if (item_list.push_back(new Item_field(NULL,NULL,"*"))) void(item_list.push_back(new Item_field(NULL,NULL,"*")));
return -1;
if (lex->exchange) if (lex->exchange)
{ {
if (lex->exchange->dumpfile) if (lex->exchange->dumpfile)
{ result=new select_dump(lex->exchange);
if (!(result=new select_dump(lex->exchange)))
return -1;
}
else else
{ result=new select_export(lex->exchange);
if (!(result=new select_export(lex->exchange)))
return -1;
}
} }
else if (!(result=new select_send())) else result=new select_send();
return -1; if (result)
else
{ {
res=mysql_select(thd,resulting,item_list, res=mysql_select(thd,resulting,item_list,
NULL, NULL,
ftfunc_list, ftfunc_list,
(ORDER*) NULL, (ORDER*) NULL,
(ORDER*) NULL, (ORDER*) NULL,
NULL, NULL,
(ORDER*) NULL, (ORDER*) NULL,
thd->options, thd->options,
result); result);
if (res) if (res)
result->abort(); result->abort();
delete result;
} }
delete result; delete create_result;
return res; return res;
} }
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