Loading sql/mysql_priv.h +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading sql/sql_class.h +1 −1 Original line number Diff line number Diff line Loading @@ -608,7 +608,7 @@ class Unique :public Sql_alloc 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; } Loading sql/sql_lex.h +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading sql/sql_parse.cc +67 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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)) Loading Loading @@ -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) Loading Loading @@ -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) Loading sql/sql_unions.cc 0 → 100644 +33 −0 Original line number Diff line number Diff line /* 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) { } } Loading
sql/mysql_priv.h +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading
sql/sql_class.h +1 −1 Original line number Diff line number Diff line Loading @@ -608,7 +608,7 @@ class Unique :public Sql_alloc 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; } Loading
sql/sql_lex.h +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
sql/sql_parse.cc +67 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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)) Loading Loading @@ -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) Loading Loading @@ -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) Loading
sql/sql_unions.cc 0 → 100644 +33 −0 Original line number Diff line number Diff line /* 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) { } }