mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge sinisa@work.mysql.com:/home/bk/mysql-4.0
into sinisa.nasamreza.org:/mnt/hdc/Sinisa/mysql-4.0
This commit is contained in:
commit
b13388806d
6 changed files with 127 additions and 5 deletions
|
@ -232,6 +232,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
|
|||
bool mysql_change_db(THD *thd,const char *name);
|
||||
void mysql_parse(THD *thd,char *inBuf,uint length);
|
||||
void mysql_init_select(LEX *lex);
|
||||
void mysql_new_select(LEX *lex);
|
||||
void init_max_user_conn(void);
|
||||
void free_max_user_conn(void);
|
||||
pthread_handler_decl(handle_one_connection,arg);
|
||||
|
@ -304,6 +305,7 @@ int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
|
|||
List<Item_func_match> &ftfuncs,
|
||||
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
|
||||
uint select_type,select_result *result);
|
||||
int mysql_union(THD *thd,LEX *lex, uint no);
|
||||
Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
|
||||
Item_result_field ***copy_func, Field **from_field,
|
||||
bool group,bool modify_item);
|
||||
|
|
|
@ -608,7 +608,7 @@ public:
|
|||
bool do_delete;
|
||||
public:
|
||||
multi_delete(TABLE_LIST *dt, thr_lock_type o, uint n)
|
||||
: delete_tables (dt), lock_option(o), deleted(0), num_of_tables(n), error(0)
|
||||
: delete_tables(dt), deleted(0), num_of_tables(n), error(0), lock_option(o)
|
||||
{
|
||||
thd = current_thd; do_delete = false;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ enum enum_sql_command {
|
|||
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS,
|
||||
SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
|
||||
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
|
||||
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE
|
||||
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE, SQLCOM_UNION_SELECT
|
||||
};
|
||||
|
||||
enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
|
||||
|
|
|
@ -47,6 +47,7 @@ static void mysql_init_query(THD *thd);
|
|||
static void remove_escape(char *name);
|
||||
static void refresh_status(void);
|
||||
static bool append_file_to_dir(char **filename_ptr, char *table_name);
|
||||
static inline int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables);
|
||||
|
||||
const char *any_db="*any*"; // Special symbol for check_access
|
||||
|
||||
|
@ -1719,6 +1720,30 @@ mysql_execute_command(void)
|
|||
close_thread_tables(thd);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_UNION_SELECT:
|
||||
{
|
||||
uint total_selects = select_lex->select_number; total_selects++;
|
||||
SQL_LIST *total=(SQL_LIST *) thd->calloc(sizeof(SQL_LIST));
|
||||
if (select_lex->options & SELECT_DESCRIBE)
|
||||
lex->exchange=0;
|
||||
res = link_in_large_list_and_check_acl(thd,lex,total);
|
||||
if (res == -1)
|
||||
{
|
||||
res=0;
|
||||
break;
|
||||
}
|
||||
if (res && (res=check_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, any_db)))
|
||||
{
|
||||
res=0;
|
||||
break;
|
||||
}
|
||||
if (!(res=open_and_lock_tables(thd,(TABLE_LIST *)total->first)))
|
||||
{
|
||||
res=mysql_union(thd,lex,total_selects);
|
||||
if (res==-1) res=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_DROP_TABLE:
|
||||
{
|
||||
if (check_table_access(thd,DROP_ACL,tables))
|
||||
|
@ -2405,6 +2430,14 @@ mysql_init_select(LEX *lex)
|
|||
select_lex->next = (SELECT_LEX *)NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mysql_new_select(LEX *lex)
|
||||
{
|
||||
uint select_no=lex->select->select_number;
|
||||
SELECT_LEX *select_lex = (SELECT_LEX *)sql_calloc(sizeof(SELECT_LEX));
|
||||
lex->select->next=select_lex;
|
||||
lex->select=select_lex; lex->select->select_number = ++select_no;
|
||||
}
|
||||
|
||||
void
|
||||
mysql_parse(THD *thd,char *inBuf,uint length)
|
||||
|
@ -2838,6 +2871,40 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
|||
DBUG_RETURN(ptr);
|
||||
}
|
||||
|
||||
static inline 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 : "";
|
||||
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
|
||||
return -1;
|
||||
}
|
||||
if (sl->table_list.first == (byte *)NULL) continue;
|
||||
TABLE_LIST *cursor,*aux=(TABLE_LIST*) sl->table_list.first;
|
||||
if (aux)
|
||||
{
|
||||
if (check_table_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL , aux))
|
||||
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;
|
||||
link_in_list(tables,(byte*)aux,(byte**) &aux->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (tables->first) ? 0 : 1;
|
||||
}
|
||||
|
||||
void add_join_on(TABLE_LIST *b,Item *expr)
|
||||
{
|
||||
if (!b->on_expr)
|
||||
|
|
33
sql/sql_unions.cc
Normal file
33
sql/sql_unions.cc
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & Monty & Sinisa
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* Union of selects */
|
||||
|
||||
#include "mysql_priv.h"
|
||||
|
||||
/*
|
||||
Do a union of selects
|
||||
*/
|
||||
|
||||
|
||||
int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
|
||||
{
|
||||
SELECT_LEX *sl;
|
||||
for (sl=&lex->select_lex;sl;sl=sl->next)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -543,7 +543,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||
opt_mi_check_type opt_to mi_check_types normal_join
|
||||
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_multi_delete table_sini_wild
|
||||
single_multi table_multi_delete table_sini_wild union union_list
|
||||
END_OF_INPUT
|
||||
|
||||
%type <NONE>
|
||||
|
@ -1260,11 +1260,11 @@ select:
|
|||
SELECT_SYM
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->sql_command= SQLCOM_SELECT;
|
||||
if (lex->sql_command!=SQLCOM_UNION_SELECT) lex->sql_command= SQLCOM_SELECT;
|
||||
lex->lock_option=TL_READ;
|
||||
mysql_init_select(lex);
|
||||
}
|
||||
select_options select_item_list select_into select_lock_type
|
||||
select_options select_item_list select_into select_lock_type union
|
||||
|
||||
select_into:
|
||||
limit_clause {}
|
||||
|
@ -3155,3 +3155,23 @@ commit:
|
|||
|
||||
rollback:
|
||||
ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;}
|
||||
|
||||
|
||||
/*
|
||||
** UNIONS : glue selects together
|
||||
*/
|
||||
|
||||
|
||||
union:
|
||||
/* empty */ {}
|
||||
| union_list
|
||||
|
||||
union_list:
|
||||
UNION_SYM
|
||||
{
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue