sql_unions.cc 3.28 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/* Copyright (C) 2000 MySQL AB
   
   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 select's */

/* UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com> */


unknown's avatar
unknown committed
23
#include "mysql_priv.h"
unknown's avatar
unknown committed
24
#include "sql_select.h"
25 26 27 28 29 30

/* Union  of selects */


int mysql_union(THD *thd,LEX *lex,uint no_of_selects) 
{
unknown's avatar
unknown committed
31 32
  SELECT_LEX *sl, *for_order=&lex->select_lex;  int res=0;
  TABLE *table=(TABLE *)NULL; TABLE_LIST *resulting=(TABLE_LIST *)NULL;
unknown's avatar
unknown committed
33 34
  for (;for_order->next;for_order=for_order->next);
  ORDER *some_order = (ORDER *)for_order->order_list.first;
unknown's avatar
unknown committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
	List<Item> list;
	List_iterator<Item> it(lex->select_lex.item_list);
	Item *item;
	TABLE_LIST *s=(TABLE_LIST*) lex->select_lex.table_list.first;
	while ((item= it++))
		if (list.push_back(item))
			return -1;
	if (setup_fields(thd,s,list,0,0))
		return -1;
	TMP_TABLE_PARAM *tmp_table_param= new TMP_TABLE_PARAM;
  count_field_types(tmp_table_param,list,0);
	tmp_table_param->end_write_records= HA_POS_ERROR; tmp_table_param->copy_field=0;
  tmp_table_param->copy_field_count=tmp_table_param->field_count=
    tmp_table_param->sum_func_count= tmp_table_param->func_count=0;
  if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, !lex->union_option,
			       0, 0, lex->select_lex.options | thd->options)))
    return 1;
	if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
		return 1;
	resulting->db=s->db ? s->db : thd->db;
	resulting->real_name=table->real_name;
	resulting->name=table->table_name;
	resulting->table=table;

  for (sl=&lex->select_lex;sl;sl=sl->next)
unknown's avatar
unknown committed
60 61
  {
    TABLE_LIST *tables=(TABLE_LIST*) sl->table_list.first;
unknown's avatar
unknown committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
		select_insert *result;
		if ((result=new select_insert(table,&list, DUP_IGNORE, true)))
		{
			res=mysql_select(thd,tables,sl->item_list,
											 sl->where,
											 sl->ftfunc_list,
											 (ORDER*) some_order,
											 (ORDER*) sl->group_list.first,
											 sl->having,
											 (ORDER*) NULL,
											 sl->options | thd->options,
											 result);
			delete result;
			if (res) 
				return res;
		}
		else
			return -1;
	}
unknown's avatar
unknown committed
81 82 83 84
  select_result *result;
  List<Item_func_match> ftfunc_list;
  ftfunc_list.empty();
  if (lex->exchange)
unknown's avatar
unknown committed
85
  {
unknown's avatar
unknown committed
86
    if (lex->exchange->dumpfile)
87
      result=new select_dump(lex->exchange);
unknown's avatar
unknown committed
88
    else
89
      result=new select_export(lex->exchange);
unknown's avatar
unknown committed
90
  }
91 92
  else result=new select_send();
  if (result)
93
  {
unknown's avatar
unknown committed
94
    res=mysql_select(thd,resulting,list,
95 96 97 98 99 100 101 102
										 NULL,
										 ftfunc_list,
										 (ORDER*) NULL,
										 (ORDER*) NULL,
										 NULL,
										 (ORDER*) NULL,
										 thd->options,
										 result);
unknown's avatar
unknown committed
103 104
    if (res)
      result->abort();
105
		delete result;
106
  }
unknown's avatar
unknown committed
107 108
	else
		res=-1;
unknown's avatar
unknown committed
109
  return res;
110
}