~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2002-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
17
  Derived tables
18
  These were introduced by Sinisa <sinisa@mysql.com>
19
*/
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
20
#include <drizzled/server_includes.h>
21
#include <drizzled/sql_select.h>
1 by brian
clean slate
22
23
/*
24
  Call given derived table processor (preparing or filling tables)
25
26
  SYNOPSIS
27
    mysql_handle_derived()
28
    lex                 LEX for this thread
29
    processor           procedure of derived table processing
30
31
  RETURN
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
32
    false  OK
33
    true   Error
1 by brian
clean slate
34
*/
35
bool
327.2.4 by Brian Aker
Refactoring table.h
36
mysql_handle_derived(LEX *lex, bool (*processor)(THD*, LEX*, TableList*))
1 by brian
clean slate
37
{
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
38
  bool res= false;
1 by brian
clean slate
39
  if (lex->derived_tables)
40
  {
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
41
    lex->thd->derived_tables_processing= true;
1 by brian
clean slate
42
    for (SELECT_LEX *sl= lex->all_selects_list;
43
	 sl;
44
	 sl= sl->next_select_in_list())
45
    {
327.2.4 by Brian Aker
Refactoring table.h
46
      for (TableList *cursor= sl->get_table_list();
1 by brian
clean slate
47
	   cursor;
48
	   cursor= cursor->next_local)
49
      {
50
	if ((res= (*processor)(lex->thd, lex, cursor)))
51
	  goto out;
52
      }
53
      if (lex->describe)
54
      {
55
	/*
56
	  Force join->join_tmp creation, because we will use this JOIN
57
	  twice for EXPLAIN and we have to have unchanged join for EXPLAINing
58
	*/
59
	sl->uncacheable|= UNCACHEABLE_EXPLAIN;
60
	sl->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
61
      }
62
    }
63
  }
64
out:
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
65
  lex->thd->derived_tables_processing= false;
1 by brian
clean slate
66
  return res;
67
}
68
69
70
/*
71
  Create temporary table structure (but do not fill it)
72
73
  SYNOPSIS
74
    mysql_derived_prepare()
75
    thd			Thread handle
76
    lex                 LEX for this thread
327.2.4 by Brian Aker
Refactoring table.h
77
    orig_table_list     TableList for the upper SELECT
1 by brian
clean slate
78
79
  IMPLEMENTATION
80
    Derived table is resolved with temporary table.
81
327.2.4 by Brian Aker
Refactoring table.h
82
    After table creation, the above TableList is updated with a new table.
1 by brian
clean slate
83
84
    This function is called before any command containing derived table
85
    is executed.
86
87
    Derived tables is stored in thd->derived_tables and freed in
88
    close_thread_tables()
89
90
  RETURN
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
91
    false  OK
92
    true   Error
1 by brian
clean slate
93
*/
94
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
95
bool mysql_derived_prepare(THD *thd, LEX *lex __attribute__((unused)),
327.2.4 by Brian Aker
Refactoring table.h
96
                           TableList *orig_table_list)
1 by brian
clean slate
97
{
98
  SELECT_LEX_UNIT *unit= orig_table_list->derived;
151 by Brian Aker
Ulonglong to uint64_t
99
  uint64_t create_options;
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
100
  bool res= false;
1 by brian
clean slate
101
  if (unit)
102
  {
103
    SELECT_LEX *first_select= unit->first_select();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
104
    Table *table= 0;
1 by brian
clean slate
105
    select_union *derived_result;
106
107
    /* prevent name resolving out of derived table */
108
    for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
109
      sl->context.outer_context= 0;
110
111
    if (!(derived_result= new select_union))
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
112
      return(true); // out of memory
1 by brian
clean slate
113
114
    // st_select_lex_unit::prepare correctly work for single select
115
    if ((res= unit->prepare(thd, derived_result, 0)))
116
      goto exit;
117
118
    create_options= (first_select->options | thd->options |
119
                     TMP_TABLE_ALL_COLUMNS);
120
    /*
121
      Temp table is created so that it hounours if UNION without ALL is to be 
122
      processed
123
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
124
      As 'distinct' parameter we always pass false (0), because underlying
1 by brian
clean slate
125
      query will control distinct condition by itself. Correct test of
126
      distinct underlying query will be is_union &&
127
      !unit->union_distinct->next_select() (i.e. it is union and last distinct
128
      SELECT is last SELECT of UNION).
129
    */
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
130
    if ((res= derived_result->create_result_table(thd, &unit->types, false,
1 by brian
clean slate
131
                                                  create_options,
132
                                                  orig_table_list->alias,
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
133
                                                  false)))
1 by brian
clean slate
134
      goto exit;
135
136
    table= derived_result->table;
137
138
exit:
139
    /*
140
      if it is preparation PS only or commands that need only VIEW structure
141
      then we do not need real data and we can skip execution (and parameters
142
      is not defined, too)
143
    */
144
    if (res)
145
    {
146
      if (table)
372.1.1 by Grant Limberg
Fix to link sql_derive with ./configure --with-debug
147
	  table->free_tmp_table(thd);
1 by brian
clean slate
148
      delete derived_result;
149
    }
150
    else
151
    {
152
      if (!thd->fill_derived_tables())
153
      {
154
	delete derived_result;
155
	derived_result= NULL;
156
      }
157
      orig_table_list->derived_result= derived_result;
158
      orig_table_list->table= table;
159
      orig_table_list->table_name=        table->s->table_name.str;
160
      orig_table_list->table_name_length= table->s->table_name.length;
161
      table->derived_select_number= first_select->select_number;
162
      table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
163
      orig_table_list->db= (char *)"";
164
      orig_table_list->db_length= 0;
165
      // Force read of table stats in the optimizer
166
      table->file->info(HA_STATUS_VARIABLE);
167
      /* Add new temporary table to list of open derived tables */
168
      table->next= thd->derived_tables;
169
      thd->derived_tables= table;
170
    }
171
  }
172
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
173
  return(res);
1 by brian
clean slate
174
}
175
176
177
/*
178
  fill derived table
179
180
  SYNOPSIS
181
    mysql_derived_filling()
182
    thd			Thread handle
183
    lex                 LEX for this thread
184
    unit                node that contains all SELECT's for derived tables
327.2.4 by Brian Aker
Refactoring table.h
185
    orig_table_list     TableList for the upper SELECT
1 by brian
clean slate
186
187
  IMPLEMENTATION
188
    Derived table is resolved with temporary table. It is created based on the
189
    queries defined. After temporary table is filled, if this is not EXPLAIN,
190
    then the entire unit / node is deleted. unit is deleted if UNION is used
191
    for derived table and node is deleted is it is a  simple SELECT.
192
    If you use this function, make sure it's not called at prepare.
193
    Due to evaluation of LIMIT clause it can not be used at prepared stage.
194
195
  RETURN
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
196
    false  OK
197
    true   Error
1 by brian
clean slate
198
*/
199
327.2.4 by Brian Aker
Refactoring table.h
200
bool mysql_derived_filling(THD *thd, LEX *lex, TableList *orig_table_list)
1 by brian
clean slate
201
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
202
  Table *table= orig_table_list->table;
1 by brian
clean slate
203
  SELECT_LEX_UNIT *unit= orig_table_list->derived;
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
204
  bool res= false;
1 by brian
clean slate
205
206
  /*check that table creation pass without problem and it is derived table */
207
  if (table && unit)
208
  {
209
    SELECT_LEX *first_select= unit->first_select();
210
    select_union *derived_result= orig_table_list->derived_result;
211
    SELECT_LEX *save_current_select= lex->current_select;
212
    if (unit->is_union())
213
    {
214
      // execute union without clean up
215
      res= unit->exec();
216
    }
217
    else
218
    {
219
      unit->set_limit(first_select);
220
      if (unit->select_limit_cnt == HA_POS_ERROR)
221
	first_select->options&= ~OPTION_FOUND_ROWS;
222
223
      lex->current_select= first_select;
224
      res= mysql_select(thd, &first_select->ref_pointer_array,
327.2.4 by Brian Aker
Refactoring table.h
225
			(TableList*) first_select->table_list.first,
1 by brian
clean slate
226
			first_select->with_wild,
227
			first_select->item_list, first_select->where,
228
			(first_select->order_list.elements+
229
			 first_select->group_list.elements),
327.2.3 by Brian Aker
Refactoring of class Table
230
			(order_st *) first_select->order_list.first,
231
			(order_st *) first_select->group_list.first,
232
			first_select->having, (order_st*) NULL,
1 by brian
clean slate
233
			(first_select->options | thd->options |
234
			 SELECT_NO_UNLOCK),
235
			derived_result, unit, first_select);
236
    }
237
238
    if (!res)
239
    {
240
      /*
327.2.4 by Brian Aker
Refactoring table.h
241
        Here we entirely fix both TableList and list of SELECT's as
1 by brian
clean slate
242
        there were no derived tables
243
      */
244
      if (derived_result->flush())
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
245
        res= true;
1 by brian
clean slate
246
247
      if (!lex->describe)
248
        unit->cleanup();
249
    }
250
    else
251
      unit->cleanup();
252
    lex->current_select= save_current_select;
253
  }
254
  return res;
255
}