~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_derived.cc

  • Committer: Brian Aker
  • Date: 2009-01-17 02:46:52 UTC
  • Revision ID: brian@gir-3.local-20090117024652-4ducefje08ajbs1q
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
(we always quote).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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)
35
32
    false  OK
36
33
    true   Error
37
34
*/
38
 
bool mysql_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|= UNCACHEABLE_EXPLAIN;
58
 
        sl->master_unit()->uncacheable|= 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
 
88
91
    false  OK
89
92
    true   Error
90
93
*/
91
 
bool mysql_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
121
      Temp table is created so that it hounours if UNION without ALL is to be
116
122
      processed
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
 
        table->free_tmp_table(session);
 
147
          table->free_tmp_table(session);
141
148
      delete derived_result;
142
149
    }
143
150
    else
144
151
    {
145
 
      if (! session->fill_derived_tables())
 
152
      if (!session->fill_derived_tables())
146
153
      {
147
 
        delete derived_result;
148
 
        derived_result= NULL;
 
154
        delete derived_result;
 
155
        derived_result= NULL;
149
156
      }
150
157
      orig_table_list->derived_result= derived_result;
151
158
      orig_table_list->table= table;
152
159
      orig_table_list->table_name=        table->s->table_name.str;
153
160
      orig_table_list->table_name_length= table->s->table_name.length;
154
161
      table->derived_select_number= first_select->select_number;
155
 
      table->s->tmp_table= message::Table::TEMPORARY;
 
162
      table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
156
163
      orig_table_list->db= (char *)"";
157
164
      orig_table_list->db_length= 0;
158
 
      /* Force read of table stats in the optimizer */
159
 
      table->cursor->info(HA_STATUS_VARIABLE);
 
165
      // Force read of table stats in the optimizer
 
166
      table->file->info(HA_STATUS_VARIABLE);
160
167
      /* Add new temporary table to list of open derived tables */
161
168
      table->next= session->derived_tables;
162
169
      session->derived_tables= table;
166
173
  return(res);
167
174
}
168
175
 
 
176
 
169
177
/*
170
178
  fill derived table
171
179
 
188
196
    false  OK
189
197
    true   Error
190
198
*/
 
199
 
191
200
bool mysql_derived_filling(Session *session, LEX *lex, TableList *orig_table_list)
192
201
{
193
202
  Table *table= orig_table_list->table;
194
 
  Select_Lex_Unit *unit= orig_table_list->derived;
 
203
  SELECT_LEX_UNIT *unit= orig_table_list->derived;
195
204
  bool res= false;
196
205
 
197
206
  /*check that table creation pass without problem and it is derived table */
198
207
  if (table && unit)
199
208
  {
200
 
    Select_Lex *first_select= unit->first_select();
 
209
    SELECT_LEX *first_select= unit->first_select();
201
210
    select_union *derived_result= orig_table_list->derived_result;
202
 
    Select_Lex *save_current_select= lex->current_select;
 
211
    SELECT_LEX *save_current_select= lex->current_select;
203
212
    if (unit->is_union())
204
213
    {
205
 
      /* execute union without clean up */
 
214
      // execute union without clean up
206
215
      res= unit->exec();
207
216
    }
208
217
    else
209
218
    {
210
219
      unit->set_limit(first_select);
211
220
      if (unit->select_limit_cnt == HA_POS_ERROR)
212
 
              first_select->options&= ~OPTION_FOUND_ROWS;
 
221
        first_select->options&= ~OPTION_FOUND_ROWS;
213
222
 
214
223
      lex->current_select= first_select;
215
224
      res= mysql_select(session, &first_select->ref_pointer_array,
216
 
                        (TableList*) first_select->table_list.first,
217
 
                        first_select->with_wild,
218
 
                        first_select->item_list, first_select->where,
219
 
                        (first_select->order_list.elements+
220
 
                        first_select->group_list.elements),
221
 
                        (order_st *) first_select->order_list.first,
222
 
                        (order_st *) first_select->group_list.first,
223
 
                        first_select->having,
224
 
                        (first_select->options | session->options | SELECT_NO_UNLOCK),
225
 
                        derived_result, unit, first_select);
 
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);
226
236
    }
227
237
 
228
 
    if (! res)
 
238
    if (!res)
229
239
    {
230
240
      /*
231
241
        Here we entirely fix both TableList and list of SELECT's as
234
244
      if (derived_result->flush())
235
245
        res= true;
236
246
 
237
 
      if (! lex->describe)
 
247
      if (!lex->describe)
238
248
        unit->cleanup();
239
249
    }
240
250
    else
243
253
  }
244
254
  return res;
245
255
}
246
 
 
247
 
} /* namespace drizzled */