diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3b75eb3db714effa2a2b5cb0d4c216af95a97e11..627c1a23de370c3e3ac0d42d05f2c7b58db875b4 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -180,7 +180,7 @@ typedef struct st_lex { enum enum_ha_read_modes ha_read_mode; enum ha_rkey_function ha_rkey_mode; enum enum_enable_or_disable alter_keys_onoff; - uint grant,grant_tot_col,which_columns; + uint grant,grant_tot_col,which_columns, union_option; thr_lock_type lock_option; bool drop_primary,drop_if_exists,local_file; bool in_comment,ignore_space,verbose,simple_alter, option_type; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ea8e59808529d5eb7469c189fd23a61236a13665..0fe8ccb881f53d772f005346e27737c579491246 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1761,7 +1761,9 @@ mysql_execute_command(void) for (TABLE_LIST *cursor=(TABLE_LIST *)sl->table_list.first;cursor;cursor=cursor->next) cursor->table= ((TABLE_LIST*) cursor->table)->table; } + ha_rows save_it=thd->offset_limit; thd->offset_limit=0; res=mysql_union(thd,lex, select_lex->select_number+1); + thd->offset_limit=save_it; } close_thread_tables(thd); break; @@ -2440,9 +2442,9 @@ mysql_init_select(LEX *lex) SELECT_LEX *select_lex = lex->select; select_lex->where=select_lex->having=0; select_lex->select_limit=current_thd->default_select_limit; - select_lex->offset_limit=0L; + select_lex->offset_limit=0; select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE; - select_lex->select_number = 0; lex->exchange = 0; + select_lex->select_number = 0; lex->exchange = 0; lex->union_option=0; lex->proc_list.first=0; select_lex->order_list.elements=select_lex->group_list.elements=0; select_lex->order_list.first=0; @@ -2915,29 +2917,31 @@ static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables) if (aux) { if (check_table_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL , aux)) - return -1; + return -1; for (;aux;aux=aux->next) { - if (!aux->db) - aux->db=(char *)current_db; - for (cursor=(TABLE_LIST *)tables->first;cursor;cursor=cursor->next) - if (!strcmp(cursor->db,aux->db) && (!strcmp(cursor->real_name,aux->real_name))) - break; - if (!cursor || !tables->first) - { - aux->lock_type= lex->lock_option; - if (!tables->next) - tables->next= (byte**) &tables->first; - 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); - } + if (!aux->db) + aux->db=(char *)current_db; + for (cursor=(TABLE_LIST *)tables->first;cursor;cursor=cursor->next) + if (!strcmp(cursor->db,aux->db) && (!strcmp(cursor->real_name,aux->real_name))) + break; + if (!cursor || !tables->first) + { + aux->lock_type= lex->lock_option; + if (!tables->next) + tables->next= (byte**) &tables->first; + 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); + } + else + aux->table=(TABLE *)cursor; } } } diff --git a/sql/sql_unions.cc b/sql/sql_unions.cc index cd0b41ac3cabfb8f6a5952b52e759b1ec05c0dfd..71b74a505fce238523cd687dc230d5ac7f4f4f80 100644 --- a/sql/sql_unions.cc +++ b/sql/sql_unions.cc @@ -72,10 +72,10 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) return res; } table=create_result->table; - List_iterator<Item> it(*(create_result->fields)); +/* List_iterator<Item> it(*(create_result->fields)); Item *item; while ((item= it++)) - fields.push_back(item); + fields.push_back(item);*/ if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))) return 1; resulting->db=tables->db ? tables->db : thd->db; @@ -88,8 +88,8 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) } else // Then we do INSERT from SELECT { - select_result *result; - if ((result=new select_insert(table, &fields, DUP_IGNORE, true))) + select_insert *result; + if ((result=new select_insert(table, create_result->fields, DUP_IGNORE, true))) { res=mysql_select(thd,tables,sl->item_list, sl->where, @@ -104,7 +104,7 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) if (res) { delete create_result; - return 1; + return res; } } else @@ -142,6 +142,8 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) result->abort(); delete result; } + else + res=-1; delete create_result; return res; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0efa4e0ad83a903ca3ba937789767371e7784294..e9c5990fe1476f5fa49d961a5459572b995b37a3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -551,7 +551,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_rkey_mode handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union union_list - precision + precision union_option END_OF_INPUT %type <NONE> @@ -3404,11 +3404,15 @@ union: | union_list union_list: - UNION_SYM + UNION_SYM union_option { LEX *lex=Lex; if (lex->exchange) YYABORT; /* Only the last SELECT can have INTO...... */ lex->sql_command=SQLCOM_UNION_SELECT; mysql_new_select(lex); lex->select->linkage=UNION_TYPE; } - select + select + +union_option: + /* empty */ {} + | ALL {Lex->union_option=1;}