~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_derived.cc

  • Committer: Brian Aker
  • Date: 2009-02-10 00:14:40 UTC
  • Revision ID: brian@tangent.org-20090210001440-qjg8eofh3h93064b
Adding Multi-threaded Scheduler into the system.

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
 
 
22
 
#include <drizzled/sql_lex.h>
23
 
#include <drizzled/select_union.h>
 
20
#include <drizzled/server_includes.h>
24
21
#include <drizzled/sql_select.h>
25
 
#include <drizzled/session.h>
26
 
 
27
 
namespace drizzled
28
 
{
29
22
 
30
23
/*
31
24
  Call given derived table processor (preparing or filling tables)
32
25
 
33
26
  SYNOPSIS
34
 
    handle_derived()
 
27
    mysql_handle_derived()
35
28
    lex                 LEX for this thread
36
29
    processor           procedure of derived table processing
37
30
 
39
32
    false  OK
40
33
    true   Error
41
34
*/
42
 
bool handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
 
35
bool
 
36
mysql_handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
43
37
{
44
38
  bool res= false;
45
39
  if (lex->derived_tables)
46
40
  {
47
41
    lex->session->derived_tables_processing= true;
48
 
    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())
49
45
    {
50
 
      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)
51
49
      {
52
 
        if ((res= (*processor)(lex->session, lex, cursor)))
53
 
          goto out;
 
50
        if ((res= (*processor)(lex->session, lex, cursor)))
 
51
          goto out;
54
52
      }
55
53
      if (lex->describe)
56
54
      {
57
 
        /*
58
 
          Force join->join_tmp creation, because we will use this JOIN
59
 
          twice for EXPLAIN and we have to have unchanged join for EXPLAINing
60
 
        */
61
 
        sl->uncacheable.set(UNCACHEABLE_EXPLAIN);
62
 
        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;
63
61
      }
64
62
    }
65
63
  }
68
66
  return res;
69
67
}
70
68
 
 
69
 
71
70
/*
72
71
  Create temporary table structure (but do not fill it)
73
72
 
74
73
  SYNOPSIS
75
 
    derived_prepare()
 
74
    mysql_derived_prepare()
76
75
    session                     Thread handle
77
76
    lex                 LEX for this thread
78
77
    orig_table_list     TableList for the upper SELECT
92
91
    false  OK
93
92
    true   Error
94
93
*/
95
 
bool derived_prepare(Session *session, LEX *, TableList *orig_table_list)
 
94
 
 
95
bool mysql_derived_prepare(Session *session, LEX *,
 
96
                           TableList *orig_table_list)
96
97
{
97
98
  Select_Lex_Unit *unit= orig_table_list->derived;
98
99
  uint64_t create_options;
114
115
    if ((res= unit->prepare(session, derived_result, 0)))
115
116
      goto exit;
116
117
 
117
 
    create_options= (first_select->options | session->options | TMP_TABLE_ALL_COLUMNS);
 
118
    create_options= (first_select->options | session->options |
 
119
                     TMP_TABLE_ALL_COLUMNS);
118
120
    /*
119
121
      Temp table is created so that it hounours if UNION without ALL is to be
120
122
      processed
127
129
    */
128
130
    if ((res= derived_result->create_result_table(session, &unit->types, false,
129
131
                                                  create_options,
130
 
                                                  orig_table_list->alias)))
 
132
                                                  orig_table_list->alias,
 
133
                                                  false)))
131
134
      goto exit;
132
135
 
133
136
    table= derived_result->table;
141
144
    if (res)
142
145
    {
143
146
      if (table)
144
 
      {
145
 
        table= 0;
146
 
      }
 
147
          table->free_tmp_table(session);
147
148
      delete derived_result;
148
149
    }
149
150
    else
150
151
    {
 
152
      if (!session->fill_derived_tables())
 
153
      {
 
154
        delete derived_result;
 
155
        derived_result= NULL;
 
156
      }
151
157
      orig_table_list->derived_result= derived_result;
152
158
      orig_table_list->table= table;
153
 
      orig_table_list->setTableName(const_cast<char *>(table->getShare()->getTableName()));
154
 
      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;
155
161
      table->derived_select_number= first_select->select_number;
156
 
      orig_table_list->setSchemaName((char *)"");
 
162
      table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
 
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
 
      table->setNext(session->getDerivedTables());
162
 
      session->setDerivedTables(table);
 
168
      table->next= session->derived_tables;
 
169
      session->derived_tables= table;
163
170
    }
164
171
  }
165
172
 
166
173
  return(res);
167
174
}
168
175
 
 
176
 
169
177
/*
170
178
  fill derived table
171
179
 
172
180
  SYNOPSIS
173
 
    derived_filling()
 
181
    mysql_derived_filling()
174
182
    session                     Thread handle
175
183
    lex                 LEX for this thread
176
184
    unit                node that contains all SELECT's for derived tables
188
196
    false  OK
189
197
    true   Error
190
198
*/
191
 
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)
192
201
{
193
202
  Table *table= orig_table_list->table;
194
203
  Select_Lex_Unit *unit= orig_table_list->derived;
202
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
 
      res= select_query(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 *) first_select->order_list.first,
222
 
                        (Order *) first_select->group_list.first,
223
 
                        first_select->having,
224
 
                        (first_select->options | session->options | SELECT_NO_UNLOCK),
225
 
                        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);
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 */