Commit 0d3fbc29 authored by Sinisa@sinisa.nasamreza.org's avatar Sinisa@sinisa.nasamreza.org
Browse files

Merge sinisa@work.mysql.com:/home/bk/mysql-4.0

into sinisa.nasamreza.org:/mnt/hdc/Sinisa/mysql-4.0
parents 7c344a58 2252f945
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -179,6 +179,8 @@ include/my_config.h
include/my_global.h
include/mysql_version.h
include/widec.h
innobase/conftest.s1
innobase/conftest.subs
innobase/ib_config.h
innobase/ib_config.h.in
isam/isamchk
@@ -366,6 +368,7 @@ sql/share/gmon.out
sql/share/mysql
sql/share/norwegian-ny/errmsg.sys
sql/share/norwegian/errmsg.sys
sql/sql_select.cc.orig
sql/sql_yacc.cc
sql/sql_yacc.h
stamp-h
+1 −1
Original line number Diff line number Diff line
@@ -316,7 +316,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,
		 ulong select_type,select_result *result);
int mysql_union(THD *thd,LEX *lex);
int mysql_union(THD *thd,LEX *lex,select_result  *create_insert=(select_result *)NULL);
Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
			Item_result_field ***copy_func, Field **from_field,
			bool group,bool modify_item);
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ enum enum_sql_command {
  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_UNION_SELECT,
  SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER
  SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_NONE
};

enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
+127 −56
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@ 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 create_total_list_and_check_acl(THD *thd, LEX *lex,
					   TABLE_LIST **result);
					   TABLE_LIST **result, bool skip_first = false);
static int handle_create_select(THD *thd, LEX *lex, select_result *c_i);

const char *any_db="*any*";	// Special symbol for check_access

@@ -1068,7 +1069,7 @@ mysql_execute_command(void)
  int	res=0;
  THD	*thd=current_thd;
  LEX	*lex= &thd->lex;
  TABLE_LIST *tables=(TABLE_LIST*) lex->select->table_list.first;
  TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
  SELECT_LEX *select_lex = lex->select;
  DBUG_ENTER("mysql_execute_command");

@@ -1322,32 +1323,15 @@ mysql_execute_command(void)
      thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
      if (thd->select_limit < select_lex->select_limit)
	thd->select_limit= HA_POS_ERROR;		// No limit

      if (!(res=open_and_lock_tables(thd,tables->next)))
      {
			if ((result=new select_create(tables->db ? tables->db : thd->db,
				      tables->real_name, &lex->create_info,
				      lex->create_list,
				      lex->key_list,
				      select_lex->item_list,lex->duplicates)))
	{
	  res=mysql_select(thd,tables->next,select_lex->item_list,
			   select_lex->where,
                           select_lex->ftfunc_list,
			   (ORDER*) select_lex->order_list.first,
			   (ORDER*) select_lex->group_list.first,
			   select_lex->having,
			   (ORDER*) lex->proc_list.first,
			   select_lex->options | thd->options,
			   result);
	  if (res)
	    result->abort();
	  delete result;
	}
				res=handle_create_select(thd,lex,result);
			else
				res= -1;
		}
    }
    else // regular create
    {
      res = mysql_create_table(thd,tables->db ? tables->db : thd->db,
@@ -1612,6 +1596,45 @@ mysql_execute_command(void)
    if (thd->select_limit < select_lex->select_limit)
      thd->select_limit= HA_POS_ERROR;		// No limit

		if (lex->select_lex.next)
		{
			TABLE_LIST *total;
			if ((res = create_total_list_and_check_acl(thd,lex,&total)))
				goto error;
			if (check_dup(thd,total->db,total->real_name,total->next))
			{
				net_printf(&thd->net,ER_INSERT_TABLE_USED,total->real_name);
				DBUG_VOID_RETURN;
			}
			total->lock_type=TL_WRITE;				// update first table
			{
				TABLE_LIST *table;
				for (table = total->next ; table ; table=table->next)
					table->lock_type= lex->lock_option;
			}
			if (!(res=open_and_lock_tables(thd, total)))
			{
				if ((result=new select_insert(total->table,&lex->field_list,
																			lex->sql_command == SQLCOM_REPLACE_SELECT ?
																			DUP_REPLACE : DUP_IGNORE)))
				{

					for (SELECT_LEX *sl=&lex->select_lex; sl; sl=sl->next)
					{
						TABLE_LIST *help=(TABLE_LIST *)sl->table_list.first;
						if (sl==&lex->select_lex) help=help->next;
						for (TABLE_LIST *cursor= help;
								 cursor;
								 cursor=cursor->next)
							cursor->table= ((TABLE_LIST*) cursor->table)->table;
					}
					res=mysql_union(thd,lex,result);
				}
				close_thread_tables(thd);
			}
		}
		else
		{
			if (check_dup(thd,tables->db,tables->real_name,tables->next))
			{
				net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
@@ -1643,6 +1666,7 @@ mysql_execute_command(void)
				else
					res= -1;
			}
    }
#ifdef DELETE_ITEMS
    delete select_lex->having;
    delete select_lex->where;
@@ -2434,6 +2458,7 @@ mysql_init_query(THD *thd)
  thd->fatal_error=0;				// Safety
  thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
  thd->sent_row_count=thd->examined_row_count=0;
	thd->lex.sql_command=SQLCOM_NONE;
  DBUG_VOID_RETURN;
}

@@ -2910,7 +2935,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
*/

static int create_total_list_and_check_acl(THD *thd, LEX *lex,
					   TABLE_LIST **result)
					   TABLE_LIST **result, bool skip_first = false)
{
  SELECT_LEX *sl;
  TABLE_LIST **new_table_list= result, *aux;
@@ -2926,6 +2951,7 @@ static int create_total_list_and_check_acl(THD *thd, LEX *lex,
      return -1;
    }
    aux= (TABLE_LIST*) sl->table_list.first;
		if (skip_first && sl == &lex->select_lex) aux=aux->next;
    if (aux)
    {
      TABLE_LIST *next;
@@ -2961,6 +2987,51 @@ static int create_total_list_and_check_acl(THD *thd, LEX *lex,
  return 0;
}

static int handle_create_select(THD *thd, LEX *lex, select_result *c_i)
{
	int res;
	if (lex->select_lex.next)
	{
		TABLE_LIST *total;
		if ((res = create_total_list_and_check_acl(thd,lex,&total,true)))
			return res;
    if (!(res=open_and_lock_tables(thd, total)))
    {
      for (SELECT_LEX *sl=&lex->select_lex; sl; sl=sl->next)
      {
				TABLE_LIST *help=(TABLE_LIST *)sl->table_list.first;
				if (sl==&lex->select_lex) help=help->next;
				for (TABLE_LIST *cursor= help;
						 cursor;
						 cursor=cursor->next)
					cursor->table= ((TABLE_LIST*) cursor->table)->table;
      }
      res=mysql_union(thd,lex,c_i);
    }
    close_thread_tables(thd);
	}
	else
	{
		TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
		SELECT_LEX *select_lex=&lex->select_lex;
		if (!(res=open_and_lock_tables(thd,tables->next)))
		{
			res=mysql_select(thd,tables->next,select_lex->item_list,
											 select_lex->where,
											 select_lex->ftfunc_list,
											 (ORDER*) select_lex->order_list.first,
											 (ORDER*) select_lex->group_list.first,
											 select_lex->having,
											 (ORDER*) lex->proc_list.first,
											 select_lex->options | thd->options,
											 c_i);
		}
	}
	if (res)
		c_i->abort();
	delete c_i;
	return res;
}

void add_join_on(TABLE_LIST *b,Item *expr)
{
+7 −13
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
#include "sql_select.h"


int mysql_union(THD *thd, LEX *lex)
int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result *)NULL)
{
  SELECT_LEX *sl, *last_sl;
  ORDER *order;
@@ -60,6 +60,7 @@ int mysql_union(THD *thd, LEX *lex)

    /* Create a list of items that will be in the result set */
    first_table= (TABLE_LIST*) lex->select_lex.table_list.first;
		if (create_insert) first_table=first_table->next;
    while ((item= it++))
      if (item_list.push_back(item))
	DBUG_RETURN(-1);
@@ -95,7 +96,8 @@ int mysql_union(THD *thd, LEX *lex)
    if (thd->select_limit == HA_POS_ERROR)
      sl->options&= ~OPTION_FOUND_ROWS;

    res=mysql_select(thd,(TABLE_LIST*) sl->table_list.first,
    res=mysql_select(thd,(sl == &lex->select_lex) ? first_table : 
				 (TABLE_LIST*) sl->table_list.first,
		     sl->item_list,
		     sl->where,
		     sl->ftfunc_list,
@@ -114,17 +116,9 @@ int mysql_union(THD *thd, LEX *lex)
    goto exit;
  }
  delete union_result;

  /*
    Sinisa, we must also be able to handle
    CREATE TABLE ... and INSERT ... SELECT with unions

    To do this, it's probably best that we add a new handle_select() function
    which takes 'select_result' as parameter and let this internally handle
    SELECT with and without unions.
  */

  if (lex->exchange)
	if (create_insert)
		result=create_insert;
  else if (lex->exchange)
  {
    if (lex->exchange->dumpfile)
      result=new select_dump(lex->exchange);
Loading