Changes for the furtherment of UNIONS
This commit is contained in:
parent
e0d818f3ab
commit
cccb3aaf70
@ -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 @@ public:
|
|||||||
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()
|
|||||||
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()
|
|||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user