~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_derived.cc

  • Committer: Monty Taylor
  • Date: 2008-11-16 05:36:13 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116053613-bld4rqxhlkb49c02
Split out cache_row and type_holder.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
17
  Derived tables
18
18
  These were introduced by Sinisa <sinisa@mysql.com>
19
19
*/
20
 
#include "config.h"
21
 
#include "drizzled/sql_select.h"
22
 
 
23
 
namespace drizzled
24
 
{
 
20
#include <drizzled/server_includes.h>
 
21
#include <drizzled/sql_select.h>
25
22
 
26
23
/*
27
24
  Call given derived table processor (preparing or filling tables)
28
25
 
29
26
  SYNOPSIS
30
 
    handle_derived()
 
27
    mysql_handle_derived()
31
28
    lex                 LEX for this thread
32
29
    processor           procedure of derived table processing
33
30
 
35
32
    false  OK
36
33
    true   Error
37
34
*/
38
 
bool handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
 
35
bool
 
36
mysql_handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
39
37
{
40
38
  bool res= false;
41
39
  if (lex->derived_tables)
42
40
  {
43
41
    lex->session->derived_tables_processing= true;
44
 
    for (Select_Lex *sl= lex->all_selects_list; sl; sl= sl->next_select_in_list())
 
42
    for (SELECT_LEX *sl= lex->all_selects_list;
 
43
         sl;
 
44
         sl= sl->next_select_in_list())
45
45
    {
46
 
      for (TableList *cursor= sl->get_table_list(); cursor; cursor= cursor->next_local)
 
46
      for (TableList *cursor= sl->get_table_list();
 
47
           cursor;
 
48
           cursor= cursor->next_local)
47
49
      {
48
 
        if ((res= (*processor)(lex->session, lex, cursor)))
49
 
          goto out;
 
50
        if ((res= (*processor)(lex->session, lex, cursor)))
 
51
          goto out;
50
52
      }
51
53
      if (lex->describe)
52
54
      {
53
 
        /*
54
 
          Force join->join_tmp creation, because we will use this JOIN
55
 
          twice for EXPLAIN and we have to have unchanged join for EXPLAINing
56
 
        */
57
 
        sl->uncacheable.set(UNCACHEABLE_EXPLAIN);
58
 
        sl->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
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;
59
61
      }
60
62
    }
61
63
  }
64
66
  return res;
65
67
}
66
68
 
 
69
 
67
70
/*
68
71
  Create temporary table structure (but do not fill it)
69
72
 
70
73
  SYNOPSIS
71
 
    derived_prepare()
 
74
    mysql_derived_prepare()
72
75
    session                     Thread handle
73
76
    lex                 LEX for this thread
74
77
    orig_table_list     TableList for the upper SELECT
88
91
    false  OK
89
92
    true   Error
90
93
*/
91
 
bool derived_prepare(Session *session, LEX *, TableList *orig_table_list)
 
94
 
 
95
bool mysql_derived_prepare(Session *session, LEX *,
 
96
                           TableList *orig_table_list)
92
97
{
93
 
  Select_Lex_Unit *unit= orig_table_list->derived;
 
98
  SELECT_LEX_UNIT *unit= orig_table_list->derived;
94
99
  uint64_t create_options;
95
100
  bool res= false;
96
101
  if (unit)
97
102
  {
98
 
    Select_Lex *first_select= unit->first_select();
 
103
    SELECT_LEX *first_select= unit->first_select();
99
104
    Table *table= 0;
100
105
    select_union *derived_result;
101
106
 
102
107
    /* prevent name resolving out of derived table */
103
 
    for (Select_Lex *sl= first_select; sl; sl= sl->next_select())
 
108
    for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
104
109
      sl->context.outer_context= 0;
105
110
 
106
111
    if (!(derived_result= new select_union))
107
112
      return(true); // out of memory
108
113
 
109
 
    // Select_Lex_Unit::prepare correctly work for single select
 
114
    // st_select_lex_unit::prepare correctly work for single select
110
115
    if ((res= unit->prepare(session, derived_result, 0)))
111
116
      goto exit;
112
117
 
113
 
    create_options= (first_select->options | session->options | TMP_TABLE_ALL_COLUMNS);
 
118
    create_options= (first_select->options | session->options |
 
119
                     TMP_TABLE_ALL_COLUMNS);
114
120
    /*
115
 
      Temp table is created so that it hounours if UNION without ALL is to be
 
121
      Temp table is created so that it hounours if UNION without ALL is to be 
116
122
      processed
117
123
 
118
124
      As 'distinct' parameter we always pass false (0), because underlying
123
129
    */
124
130
    if ((res= derived_result->create_result_table(session, &unit->types, false,
125
131
                                                  create_options,
126
 
                                                  orig_table_list->alias)))
 
132
                                                  orig_table_list->alias,
 
133
                                                  false)))
127
134
      goto exit;
128
135
 
129
136
    table= derived_result->table;
137
144
    if (res)
138
145
    {
139
146
      if (table)
140
 
      {
141
 
        table= 0;
142
 
      }
 
147
          table->free_tmp_table(session);
143
148
      delete derived_result;
144
149
    }
145
150
    else
146
151
    {
 
152
      if (!session->fill_derived_tables())
 
153
      {
 
154
        delete derived_result;
 
155
        derived_result= NULL;
 
156
      }
147
157
      orig_table_list->derived_result= derived_result;
148
158
      orig_table_list->table= table;
149
 
      orig_table_list->setTableName(const_cast<char *>(table->getShare()->getTableName()));
150
 
      orig_table_list->table_name_length= table->getShare()->getTableNameSize();
 
159
      orig_table_list->table_name=        table->s->table_name.str;
 
160
      orig_table_list->table_name_length= table->s->table_name.length;
151
161
      table->derived_select_number= first_select->select_number;
152
 
      orig_table_list->setSchemaName((char *)"");
 
162
      table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
 
163
      orig_table_list->db= (char *)"";
153
164
      orig_table_list->db_length= 0;
154
 
      /* Force read of table stats in the optimizer */
155
 
      table->cursor->info(HA_STATUS_VARIABLE);
 
165
      // Force read of table stats in the optimizer
 
166
      table->file->info(HA_STATUS_VARIABLE);
156
167
      /* Add new temporary table to list of open derived tables */
157
 
      table->setNext(session->getDerivedTables());
158
 
      session->setDerivedTables(table);
 
168
      table->next= session->derived_tables;
 
169
      session->derived_tables= table;
159
170
    }
160
171
  }
161
172
 
162
173
  return(res);
163
174
}
164
175
 
 
176
 
165
177
/*
166
178
  fill derived table
167
179
 
168
180
  SYNOPSIS
169
 
    derived_filling()
 
181
    mysql_derived_filling()
170
182
    session                     Thread handle
171
183
    lex                 LEX for this thread
172
184
    unit                node that contains all SELECT's for derived tables
184
196
    false  OK
185
197
    true   Error
186
198
*/
187
 
bool derived_filling(Session *session, LEX *lex, TableList *orig_table_list)
 
199
 
 
200
bool mysql_derived_filling(Session *session, LEX *lex, TableList *orig_table_list)
188
201
{
189
202
  Table *table= orig_table_list->table;
190
 
  Select_Lex_Unit *unit= orig_table_list->derived;
 
203
  SELECT_LEX_UNIT *unit= orig_table_list->derived;
191
204
  bool res= false;
192
205
 
193
206
  /*check that table creation pass without problem and it is derived table */
194
207
  if (table && unit)
195
208
  {
196
 
    Select_Lex *first_select= unit->first_select();
 
209
    SELECT_LEX *first_select= unit->first_select();
197
210
    select_union *derived_result= orig_table_list->derived_result;
198
 
    Select_Lex *save_current_select= lex->current_select;
 
211
    SELECT_LEX *save_current_select= lex->current_select;
199
212
    if (unit->is_union())
200
213
    {
201
 
      /* execute union without clean up */
 
214
      // execute union without clean up
202
215
      res= unit->exec();
203
216
    }
204
217
    else
205
218
    {
206
219
      unit->set_limit(first_select);
207
220
      if (unit->select_limit_cnt == HA_POS_ERROR)
208
 
              first_select->options&= ~OPTION_FOUND_ROWS;
 
221
        first_select->options&= ~OPTION_FOUND_ROWS;
209
222
 
210
223
      lex->current_select= first_select;
211
 
      res= select_query(session, &first_select->ref_pointer_array,
212
 
                        (TableList*) first_select->table_list.first,
213
 
                        first_select->with_wild,
214
 
                        first_select->item_list, first_select->where,
215
 
                        (first_select->order_list.elements+
216
 
                        first_select->group_list.elements),
217
 
                        (Order *) first_select->order_list.first,
218
 
                        (Order *) first_select->group_list.first,
219
 
                        first_select->having,
220
 
                        (first_select->options | session->options | SELECT_NO_UNLOCK),
221
 
                        derived_result, unit, first_select);
 
224
      res= mysql_select(session, &first_select->ref_pointer_array,
 
225
                        (TableList*) first_select->table_list.first,
 
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),
 
230
                        (order_st *) first_select->order_list.first,
 
231
                        (order_st *) first_select->group_list.first,
 
232
                        first_select->having, (order_st*) NULL,
 
233
                        (first_select->options | session->options |
 
234
                         SELECT_NO_UNLOCK),
 
235
                        derived_result, unit, first_select);
222
236
    }
223
237
 
224
 
    if (! res)
 
238
    if (!res)
225
239
    {
226
240
      /*
227
241
        Here we entirely fix both TableList and list of SELECT's as
230
244
      if (derived_result->flush())
231
245
        res= true;
232
246
 
233
 
      if (! lex->describe)
 
247
      if (!lex->describe)
234
248
        unit->cleanup();
235
249
    }
236
250
    else
239
253
  }
240
254
  return res;
241
255
}
242
 
 
243
 
} /* namespace drizzled */