Commit 147de1e5 authored by Sinisa@sinisa.nasamreza.org's avatar Sinisa@sinisa.nasamreza.org
Browse files

UNION stuff mainly.

parent 9e9f21a5
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -421,7 +421,7 @@ class select_result :public Sql_alloc {
  virtual int prepare(List<Item> &list) { return 0; }
  virtual bool send_fields(List<Item> &list,uint flag)=0;
  virtual bool send_data(List<Item> &items)=0;
  virtual void initialize_tables (JOIN *join=0) {};
  virtual void initialize_tables (JOIN *join=0) {}
  virtual void send_error(uint errcode,const char *err)=0;
  virtual bool send_eof()=0;
  virtual void abort() {}
@@ -475,14 +475,13 @@ class select_dump :public select_result {
  bool send_eof();
};
class select_insert :public select_result {
 protected:
 public:
  TABLE *table;
  List<Item> *fields;
  uint save_time_stamp;
  ulonglong last_insert_id;
  COPY_INFO info;

public:
  select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic)
    :table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0)
    {
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@

/* Delete of records */

/* Multi-table deletes were introduced by Monty and Sinisa */

#include "mysql_priv.h"
#include "ha_innobase.h"
#include "sql_select.h"
+7 −7
Original line number Diff line number Diff line
@@ -2445,13 +2445,13 @@ 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;
  lex->select->item_list = lex->select_lex.item_list; 
  lex->select->item_list.empty();
  lex->select->table_list = lex->select_lex.table_list; 
  lex->select->table_list.elements=0;
  lex->select->table_list.first=0;
  lex->select->table_list.next= (byte**) &lex->select->table_list.first;
  lex->select=select_lex; select_lex->select_number = ++select_no;
  select_lex->table_list.elements=0;
  select_lex->table_list.first=0;
  select_lex->table_list.next= (byte**) &select_lex->table_list.first;
  select_lex->item_list.empty(); select_lex->when_list.empty(); 
  select_lex->expr_list.empty();  select_lex->interval_list.empty(); 
  select_lex->use_index.empty(); select_lex->ftfunc_list.empty();
}

void
+90 −23
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 */
#include "mysql_priv.h"


/* 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)
  SELECT_LEX *sl, *for_order=&lex->select_lex; uint no=0; int res;
  List<Item> fields;     TABLE *table;
  for (;for_order->next;for_order=for_order->next);
  ORDER *some_order = (ORDER *)for_order->order_list.first;
  for (sl=&lex->select_lex;sl;sl=sl->next, no++)
  {
    TABLE_LIST *tables=(TABLE_LIST*) sl->table_list.first;
    if (!no) // First we do CREATE from SELECT
    {
      select_create *result;
      lex->create_info.options=HA_LEX_CREATE_TMP_TABLE;
      if ((result=new select_create(tables->db ? tables->db : thd->db,
				    NULL, &lex->create_info,
				    lex->create_list,
				    lex->key_list,
				    sl->item_list,DUP_IGNORE)))
      {
	res=mysql_select(thd,tables,sl->item_list,
			 sl->where,
			 sl->ftfunc_list,
			 (ORDER*) NULL,
			 (ORDER*) sl->group_list.first,
			 sl->having,
			 (ORDER*) some_order,
			 sl->options | thd->options,
			 result);
	if (res) 
	{
	  result->abort();
	  delete result;
	  return res;
	}
	else
	{
	  table=result->table;
	  List_iterator<Item> it(*(result->fields));
	  Item *item;
	  while ((item= it++))
	    fields.push_back(item);
	}
	delete result;
	if (reopen_table(table)) return 1;
      }
      else
	return -1;
    }
    else // Then we do INSERT from SELECT
    {
      select_result *result;
      if ((result=new select_insert(table, &fields, DUP_IGNORE)))
      {
	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 1;
      }
      else
	return -1;
    }
  }
  if (1) // Meaning if not SELECT ... INTO .... which will be done later
  {
    READ_RECORD	info;
    int error=0;
    if (send_fields(thd,fields,1)) return 1;
    SQL_SELECT	*select= new SQL_SELECT;
    select->head=table;
    select->file=*(table->io_cache);
    init_read_record(&info,thd,table,select,1,1);
    while (!(error=info.read_record(&info)) && !thd->killed)
    {
      
      if (error)
      {
	table->file->print_error(error,MYF(0));
	break;
      }
    }
    end_read_record(&info);
    delete select;
  }
  else
  {
  }
  return 0;