summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorunknown <monty@tik.mysql.fi>2001-08-02 06:29:50 +0300
committerunknown <monty@tik.mysql.fi>2001-08-02 06:29:50 +0300
commit329e5f2f35fa6640ae7dd480c9a47dd42341dafc (patch)
treefc9655d17169cd0d2593f7a2e888de91cd33dfe8 /sql/sql_parse.cc
parent7c1e2757152886d118d9eb7e8737f95cae71c4f9 (diff)
downloadmariadb-git-329e5f2f35fa6640ae7dd480c9a47dd42341dafc.tar.gz
Fix UNION
New faster list iterators Change list code to be simpler and faster Optimize count(distinct) New error messages for UNION Make create_tmp_table more general to be usable by UNION Docs/manual.texi: Changelog include/mysqld_error.h: Add new error messages needed for UNION mysql-test/r/union.result: New tests for UNION mysql-test/t/analyse.test: Add missing drop table mysql-test/t/union.test: new tests for UNION sql/Makefile.am: Change name of sql_unions.cc to sql_union.cc sql/item.cc: Use List_iterator_fast sql/item_cmpfunc.cc: Use List_iterator_fast sql/item_func.cc: Use List_iterator_fast sql/item_sum.cc: Use List_iterator_fast Optimize count(distinct) Cleanup of indentation and comments sql/item_sum.h: Optimize count(distinct) sql/key.cc: Use List_iterator_fast sql/mysql_priv.h: Add new option bits sql/opt_sum.cc: Use List_iterator_fast sql/share/Makefile.am: Add 'fix_errors' label sql/share/czech/errmsg.txt: Add new error messages needed for UNION sql/share/danish/errmsg.txt: Add new error messages needed for UNION sql/share/dutch/errmsg.txt: Add new error messages needed for UNION sql/share/english/errmsg.txt: Add new error messages needed for UNION sql/share/estonian/errmsg.txt: Add new error messages needed for UNION sql/share/french/errmsg.txt: Add new error messages needed for UNION sql/share/german/errmsg.txt: Add new error messages needed for UNION sql/share/greek/errmsg.txt: Add new error messages needed for UNION sql/share/hungarian/errmsg.txt: Add new error messages needed for UNION sql/share/italian/errmsg.txt: Add new error messages needed for UNION sql/share/japanese/errmsg.txt: Add new error messages needed for UNION sql/share/korean/errmsg.txt: Add new error messages needed for UNION sql/share/norwegian-ny/errmsg.txt: Add new error messages needed for UNION sql/share/norwegian/errmsg.txt: Add new error messages needed for UNION sql/share/polish/errmsg.txt: Add new error messages needed for UNION sql/share/portuguese/errmsg.txt: Add new error messages needed for UNION sql/share/romanian/errmsg.txt: Add new error messages needed for UNION sql/share/russian/errmsg.txt: Add new error messages needed for UNION sql/share/slovak/errmsg.txt: Add new error messages needed for UNION sql/share/spanish/errmsg.txt: Add new error messages needed for UNION sql/share/swedish/errmsg.txt: Add new error messages needed for UNION sql/sql_analyse.cc: Use List_iterator_fast sql/sql_base.cc: Use List_iterator_fast Add new argument to setup_fields sql/sql_class.cc: Use List_iterator_fast sql/sql_class.h: Create new class for UNION sql/sql_handler.cc: Use List_iterator_fast sql/sql_insert.cc: Use List_iterator_fast sql/sql_lex.h: Cleanup sql/sql_list.cc: Faster iteration of lists sql/sql_list.h: Faster iterations of lists sql/sql_load.cc: Use List_iterator_fast sql/sql_parse.cc: Fix UNION code sql/sql_select.cc: Use List_iterator_fast Make create_tmp_table more general to be usable by UNION sql/sql_select.h: Changes to speed up copy_fields() sql/sql_show.cc: Use List_iterator_fast sql/sql_table.cc: Use List_iterator_fast sql/sql_union.cc: Fix UNION code sql/sql_update.cc: Use List_iterator_fast sql/sql_yacc.yy: Fix UNION code
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc130
1 files changed, 72 insertions, 58 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6078d3ce22a..6c3205c2feb 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -47,7 +47,8 @@ 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 int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables);
+static int create_total_list_and_check_acl(THD *thd, LEX *lex,
+ TABLE_LIST **result);
const char *any_db="*any*"; // Special symbol for check_access
@@ -1737,10 +1738,10 @@ mysql_execute_command(void)
}
case SQLCOM_UNION_SELECT:
{
- SQL_LIST *total=(SQL_LIST *) thd->calloc(sizeof(SQL_LIST));
+ TABLE_LIST *total;
if (select_lex->options & SELECT_DESCRIBE)
lex->exchange=0;
- if ((res = link_in_large_list_and_check_acl(thd,lex,total)) == -1)
+ if ((res = create_total_list_and_check_acl(thd,lex,&total)) == -1)
{
res=0;
break;
@@ -1753,31 +1754,31 @@ mysql_execute_command(void)
res=0;
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;
- }
- 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;
- }
+ if (!(res=open_and_lock_tables(thd, total)))
+ {
+ /* 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);
+ }
close_thread_tables(thd);
break;
}
case SQLCOM_DROP_TABLE:
- {
- if (check_table_access(thd,DROP_ACL,tables))
- goto error; /* purecov: inspected */
- if (end_active_trans(thd))
- res= -1;
- else
- res = mysql_rm_table(thd,tables,lex->drop_if_exists);
- }
- break;
+ {
+ if (check_table_access(thd,DROP_ACL,tables))
+ goto error; /* purecov: inspected */
+ if (end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_rm_table(thd,tables,lex->drop_if_exists);
+ }
+ break;
case SQLCOM_DROP_INDEX:
if (!tables->db)
tables->db=thd->db;
@@ -2901,53 +2902,66 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
DBUG_RETURN(ptr);
}
-static int link_in_large_list_and_check_acl(THD *thd,LEX *lex,SQL_LIST *tables)
+
+/*
+** This is used for UNION to create a new table list of all used tables
+** The table_list->table entry in all used tables are set to point
+** to the entries in this list.
+*/
+
+static int create_total_list_and_check_acl(THD *thd, LEX *lex,
+ TABLE_LIST **result)
{
- SELECT_LEX *sl; const char *current_db=thd->db ? thd->db : "";
- TABLE_LIST *ptr;
- for (sl=&lex->select_lex;sl;sl=sl->next)
+ SELECT_LEX *sl;
+ TABLE_LIST **new_table_list= result, *aux;
+ const char *current_db=thd->db ? thd->db : ""; // QQ; To be removed
+
+ *new_table_list=0; // end result list
+ 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 && sl->next)
{
- 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_WRONG_USAGE,"UNION","ORDER BY");
return -1;
}
- if (sl->table_list.first == (byte *)NULL) continue;
- TABLE_LIST *cursor,*aux=(TABLE_LIST*) sl->table_list.first;
+ 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)
+ TABLE_LIST *next;
+ if (check_table_access(thd,
+ lex->exchange ?
+ SELECT_ACL | FILE_ACL : SELECT_ACL , aux))
+ return -1;
+ for (; 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);
- }
- else
- aux->table=(TABLE *)cursor;
+ TABLE_LIST *cursor;
+ next= aux->next;
+ if (!aux->db)
+ aux->db=(char *)current_db; // QQ; To be removed
+ for (cursor= *result; cursor; cursor=cursor->next)
+ if (!strcmp(cursor->db,aux->db) &&
+ (!strcmp(cursor->real_name,aux->real_name)))
+ break;
+ if (!cursor)
+ {
+ /* Add not used table to the total table list */
+ aux->lock_type= lex->lock_option;
+ if (!(cursor = (TABLE_LIST *) thd->memdup((byte*) aux,
+ sizeof(*aux))))
+ return 1;
+ *new_table_list= cursor;
+ new_table_list= &cursor->next;
+ *new_table_list=0; // end result list
+ }
+ aux->table=(TABLE *) cursor;
}
}
}
- return (tables->first) ? 0 : 1;
+ return 0;
}
+
void add_join_on(TABLE_LIST *b,Item *expr)
{
if (!b->on_expr)