~drizzle-trunk/drizzle/development

584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
353 by Brian Aker
Moved Field iterator out to its own definition.
20
#include <drizzled/server_includes.h>
21
#include <drizzled/field_iterator.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
22
#include <drizzled/table_list.h>
23
#include <drizzled/session.h>
24
#include <drizzled/table.h>
353 by Brian Aker
Moved Field iterator out to its own definition.
25
26
const char *Field_iterator_table::name()
27
{
28
  return (*ptr)->field_name;
29
}
30
31
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
32
void Field_iterator_table::set(TableList *table)
33
{
34
  ptr= table->table->field;
354 by Brian Aker
Refactor of Table methods.
35
}
36
37
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
38
void Field_iterator_table::set_table(Table *table)
39
{
40
  ptr= table->field;
353 by Brian Aker
Moved Field iterator out to its own definition.
41
}
42
43
520.1.22 by Brian Aker
Second pass of thd cleanup
44
Item *Field_iterator_table::create_item(Session *session)
353 by Brian Aker
Moved Field iterator out to its own definition.
45
{
520.1.22 by Brian Aker
Second pass of thd cleanup
46
  SELECT_LEX *select= session->lex->current_select;
353 by Brian Aker
Moved Field iterator out to its own definition.
47
520.1.22 by Brian Aker
Second pass of thd cleanup
48
  Item_field *item= new Item_field(session, &select->context, *ptr);
358 by Brian Aker
More removal on modes.
49
353 by Brian Aker
Moved Field iterator out to its own definition.
50
  return item;
51
}
52
53
54
void Field_iterator_natural_join::set(TableList *table_ref)
55
{
56
  assert(table_ref->join_columns);
57
  column_ref_it.init(*(table_ref->join_columns));
58
  cur_column_ref= column_ref_it++;
59
}
60
61
62
void Field_iterator_natural_join::next()
63
{
64
  cur_column_ref= column_ref_it++;
65
  assert(!cur_column_ref || ! cur_column_ref->table_field ||
66
              cur_column_ref->table_ref->table ==
67
              cur_column_ref->table_field->table);
68
}
69
70
71
void Field_iterator_table_ref::set_field_iterator()
72
{
73
  /*
74
    If the table reference we are iterating over is a natural join, or it is
75
    an operand of a natural join, and TableList::join_columns contains all
76
    the columns of the join operand, then we pick the columns from
77
    TableList::join_columns, instead of the  orginial container of the
78
    columns of the join operator.
79
  */
80
  if (table_ref->is_join_columns_complete)
81
  {
82
    /* Necesary, but insufficient conditions. */
83
    assert(table_ref->is_natural_join ||
84
                table_ref->nested_join ||
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
85
                ((table_ref->join_columns && /* This is a merge view. */
86
                  (table_ref->field_translation &&
87
                   table_ref->join_columns->elements ==
88
                   (ulong)(table_ref->field_translation_end -
89
                           table_ref->field_translation))) ||
353 by Brian Aker
Moved Field iterator out to its own definition.
90
                 /* This is stored table or a tmptable view. */
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
91
                 (!table_ref->field_translation &&
92
                  table_ref->join_columns->elements ==
93
                  table_ref->table->s->fields)));
353 by Brian Aker
Moved Field iterator out to its own definition.
94
    field_it= &natural_join_it;
95
  }
96
  /* This is a base table or stored view. */
97
  else
98
  {
99
    assert(table_ref->table);
100
    field_it= &table_field_it;
101
  }
102
  field_it->set(table_ref);
103
  return;
104
}
105
106
107
void Field_iterator_table_ref::set(TableList *table)
108
{
109
  assert(table);
110
  first_leaf= table->first_leaf_for_name_resolution();
111
  last_leaf=  table->last_leaf_for_name_resolution();
112
  assert(first_leaf && last_leaf);
113
  table_ref= first_leaf;
114
  set_field_iterator();
115
}
116
117
118
void Field_iterator_table_ref::next()
119
{
120
  /* Move to the next field in the current table reference. */
121
  field_it->next();
122
  /*
123
    If all fields of the current table reference are exhausted, move to
124
    the next leaf table reference.
125
  */
126
  if (field_it->end_of_fields() && table_ref != last_leaf)
127
  {
128
    table_ref= table_ref->next_name_resolution_table;
129
    assert(table_ref);
130
    set_field_iterator();
131
  }
132
}
133
134
135
const char *Field_iterator_table_ref::table_name()
136
{
137
  if (table_ref->is_natural_join)
138
    return natural_join_it.column_ref()->table_name();
139
140
  assert(!strcmp(table_ref->table_name,
141
                      table_ref->table->s->table_name.str));
142
  return table_ref->table_name;
143
}
144
145
146
const char *Field_iterator_table_ref::db_name()
147
{
148
  if (table_ref->is_natural_join)
149
    return natural_join_it.column_ref()->db_name();
150
151
  /*
152
    Test that TableList::db is the same as st_table_share::db to
153
    ensure consistency. An exception are I_S schema tables, which
154
    are inconsistent in this respect.
155
  */
156
  assert(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
157
              (table_ref->schema_table &&
158
               table_ref->table->s->db.str[0] == 0));
159
160
  return table_ref->db;
161
}
162
163
354 by Brian Aker
Refactor of Table methods.
164
353 by Brian Aker
Moved Field iterator out to its own definition.
165
/*
166
  Create new or return existing column reference to a column of a
167
  natural/using join.
168
169
  SYNOPSIS
170
    Field_iterator_table_ref::get_or_create_column_ref()
171
    parent_table_ref  the parent table reference over which the
172
                      iterator is iterating
173
174
  DESCRIPTION
175
    Create a new natural join column for the current field of the
176
    iterator if no such column was created, or return an already
177
    created natural join column. The former happens for base tables or
178
    views, and the latter for natural/using joins. If a new field is
179
    created, then the field is added to 'parent_table_ref' if it is
180
    given, or to the original table referene of the field if
181
    parent_table_ref == NULL.
182
183
  NOTES
184
    This method is designed so that when a Field_iterator_table_ref
185
    walks through the fields of a table reference, all its fields
186
    are created and stored as follows:
187
    - If the table reference being iterated is a stored table, view or
188
      natural/using join, store all natural join columns in a list
189
      attached to that table reference.
190
    - If the table reference being iterated is a nested join that is
191
      not natural/using join, then do not materialize its result
192
      fields. This is OK because for such table references
193
      Field_iterator_table_ref iterates over the fields of the nested
194
      table references (recursively). In this way we avoid the storage
195
      of unnecessay copies of result columns of nested joins.
196
197
  RETURN
198
    #     Pointer to a column of a natural join (or its operand)
199
    NULL  No memory to allocate the column
200
*/
201
202
Natural_join_column *
203
Field_iterator_table_ref::get_or_create_column_ref(TableList *parent_table_ref)
204
{
205
  Natural_join_column *nj_col;
206
  bool is_created= true;
482 by Brian Aker
Remove uint.
207
  uint32_t field_count=0;
353 by Brian Aker
Moved Field iterator out to its own definition.
208
  TableList *add_table_ref= parent_table_ref ?
209
                             parent_table_ref : table_ref;
210
211
  if (field_it == &table_field_it)
212
  {
213
    /* The field belongs to a stored table. */
214
    Field *tmp_field= table_field_it.field();
215
    nj_col= new Natural_join_column(tmp_field, table_ref);
216
    field_count= table_ref->table->s->fields;
217
  }
218
  else
219
  {
220
    /*
221
      The field belongs to a NATURAL join, therefore the column reference was
222
      already created via one of the two constructor calls above. In this case
223
      we just return the already created column reference.
224
    */
225
    assert(table_ref->is_join_columns_complete);
226
    is_created= false;
227
    nj_col= natural_join_it.column_ref();
228
    assert(nj_col);
229
  }
230
  assert(!nj_col->table_field ||
231
              nj_col->table_ref->table == nj_col->table_field->table);
232
233
  /*
234
    If the natural join column was just created add it to the list of
235
    natural join columns of either 'parent_table_ref' or to the table
236
    reference that directly contains the original field.
237
  */
238
  if (is_created)
239
  {
240
    /* Make sure not all columns were materialized. */
241
    assert(!add_table_ref->is_join_columns_complete);
242
    if (!add_table_ref->join_columns)
243
    {
244
      /* Create a list of natural join columns on demand. */
245
      if (!(add_table_ref->join_columns= new List<Natural_join_column>))
246
        return NULL;
247
      add_table_ref->is_join_columns_complete= false;
248
    }
249
    add_table_ref->join_columns->push_back(nj_col);
250
    /*
251
      If new fields are added to their original table reference, mark if
252
      all fields were added. We do it here as the caller has no easy way
253
      of knowing when to do it.
254
      If the fields are being added to parent_table_ref, then the caller
255
      must take care to mark when all fields are created/added.
256
    */
257
    if (!parent_table_ref &&
258
        add_table_ref->join_columns->elements == field_count)
259
      add_table_ref->is_join_columns_complete= true;
260
  }
261
262
  return nj_col;
263
}
264
265
266
/*
267
  Return an existing reference to a column of a natural/using join.
268
269
  SYNOPSIS
270
    Field_iterator_table_ref::get_natural_column_ref()
271
272
  DESCRIPTION
273
    The method should be called in contexts where it is expected that
274
    all natural join columns are already created, and that the column
275
    being retrieved is a Natural_join_column.
276
277
  RETURN
278
    #     Pointer to a column of a natural join (or its operand)
279
    NULL  No memory to allocate the column
280
*/
281
282
Natural_join_column *
283
Field_iterator_table_ref::get_natural_column_ref()
284
{
285
  Natural_join_column *nj_col;
286
287
  assert(field_it == &natural_join_it);
288
  /*
289
    The field belongs to a NATURAL join, therefore the column reference was
290
    already created via one of the two constructor calls above. In this case
291
    we just return the already created column reference.
292
  */
293
  nj_col= natural_join_it.column_ref();
294
  assert(nj_col &&
295
              (!nj_col->table_field ||
296
               nj_col->table_ref->table == nj_col->table_field->table));
297
  return nj_col;
298
}
299