Changes for the furtherment of UNIONS

parent dcac1079
......@@ -481,12 +481,13 @@ class select_insert :public select_result {
uint save_time_stamp;
ulonglong last_insert_id;
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)
{
bzero((char*) &info,sizeof(info));
info.handle_duplicates=duplic;
info.handle_duplicates=duplic; unions = u;
}
~select_insert();
int prepare(List<Item> &list);
......@@ -511,8 +512,8 @@ public:
HA_CREATE_INFO *create_info_par,
List<create_field> &fields_par,
List<Key> &keys_par,
List<Item> &select_fields,enum_duplicates duplic)
:select_insert (NULL, &select_fields, duplic), db(db_name),
List<Item> &select_fields,enum_duplicates duplic, bool u=false)
:select_insert (NULL, &select_fields, duplic, u), db(db_name),
name(table_name), extra_fields(&fields_par),keys(&keys_par),
create_info(create_info_par),
lock(0)
......
......@@ -1318,7 +1318,8 @@ bool select_insert::send_eof()
thd->cuted_fields);
if (last_insert_id)
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);
if (mysql_bin_log.is_open())
{
......@@ -1400,7 +1401,9 @@ bool select_create::send_eof()
mysql_unlock_tables(thd, lock);
if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table);
lock=0; table=0;
lock=0;
if (!unions)
table=0;
VOID(pthread_mutex_unlock(&LOCK_open));
}
return tmp;
......
......@@ -1754,7 +1754,15 @@ mysql_execute_command(void)
break;
}
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);
}
close_thread_tables(thd);
break;
}
......@@ -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)
{
SELECT_LEX *sl; const char *current_db=thd->db ? thd->db : "";
TABLE_LIST *ptr;
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))
{
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;
}
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)
aux->lock_type= lex->lock_option;
if (!tables->next)
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 @@
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;
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);
ORDER *some_order = (ORDER *)for_order->order_list.first;
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)
TABLE_LIST *tables=(TABLE_LIST*) sl->table_list.first;
if (!no) // First we do CREATE from SELECT
{
select_create *result;
lex->create_info.options=HA_LEX_CREATE_TMP_TABLE;
if ((result=new select_create(tables->db ? tables->db : thd->db,
NULL, &lex->create_info,
lex->create_info.db_type=DB_TYPE_MYISAM;
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->key_list,
sl->item_list,DUP_IGNORE)))
sl->item_list,DUP_IGNORE,true)))
{
res=mysql_select(thd,tables,sl->item_list,
sl->where,
sl->ftfunc_list,
(ORDER*) NULL,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) some_order,
sl->options | thd->options,
result);
if (res)
{
result->abort();
delete result;
return res;
}
table=result->table;
List_iterator<Item> it(*(result->fields));
Item *item;
while ((item= it++))
fields.push_back(item);
delete result;
if (!reopen_table(table)) return 1;
if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
return 1;
resulting->db=tables->db ? tables->db : thd->db;
resulting->real_name=table->real_name;
resulting->name=table->table_name;
resulting->table=table;
res=mysql_select(thd,tables,sl->item_list,
sl->where,
sl->ftfunc_list,
(ORDER*) NULL,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) some_order,
sl->options | thd->options,
create_result);
if (res)
{
create_result->abort();
delete create_result;
return res;
}
table=create_result->table;
List_iterator<Item> it(*(create_result->fields));
Item *item;
while ((item= it++))
fields.push_back(item);
if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
return 1;
resulting->db=tables->db ? tables->db : thd->db;
resulting->real_name=table->real_name;
resulting->name=table->table_name;
resulting->table=table;
}
else
return -1;
return -1;
}
else // Then we do INSERT from SELECT
{
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,
sl->where,
res=mysql_select(thd,tables,sl->item_list,
sl->where,
sl->ftfunc_list,
(ORDER*) some_order,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
sl->options | thd->options,
result);
delete result;
if (res) return 1;
(ORDER*) some_order,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
sl->options | thd->options,
result);
delete result;
if (res)
{
delete create_result;
return 1;
}
}
else
return -1;
{
delete create_result;
return -1;
}
}
}
select_result *result;
List<Item> item_list;
List<Item_func_match> ftfunc_list;
ftfunc_list.empty();
if (item_list.push_back(new Item_field(NULL,NULL,"*")))
return -1;
void(item_list.push_back(new Item_field(NULL,NULL,"*")));
if (lex->exchange)
{
if (lex->exchange->dumpfile)
{
if (!(result=new select_dump(lex->exchange)))
return -1;
}
result=new select_dump(lex->exchange);
else
{
if (!(result=new select_export(lex->exchange)))
return -1;
}
result=new select_export(lex->exchange);
}
else if (!(result=new select_send()))
return -1;
else
else result=new select_send();
if (result)
{
res=mysql_select(thd,resulting,item_list,
NULL,
ftfunc_list,
(ORDER*) NULL,
(ORDER*) NULL,
NULL,
(ORDER*) NULL,
thd->options,
result);
NULL,
ftfunc_list,
(ORDER*) NULL,
(ORDER*) NULL,
NULL,
(ORDER*) NULL,
thd->options,
result);
if (res)
result->abort();
delete result;
}
delete result;
delete create_result;
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