~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
{
846 by Brian Aker
Removing on typedeffed class.
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
    field_it= &natural_join_it;
83
  }
84
  /* This is a base table or stored view. */
85
  else
86
  {
87
    assert(table_ref->table);
88
    field_it= &table_field_it;
89
  }
90
  field_it->set(table_ref);
91
  return;
92
}
93
94
95
void Field_iterator_table_ref::set(TableList *table)
96
{
97
  assert(table);
98
  first_leaf= table->first_leaf_for_name_resolution();
99
  last_leaf=  table->last_leaf_for_name_resolution();
100
  assert(first_leaf && last_leaf);
101
  table_ref= first_leaf;
102
  set_field_iterator();
103
}
104
105
106
void Field_iterator_table_ref::next()
107
{
108
  /* Move to the next field in the current table reference. */
109
  field_it->next();
110
  /*
111
    If all fields of the current table reference are exhausted, move to
112
    the next leaf table reference.
113
  */
114
  if (field_it->end_of_fields() && table_ref != last_leaf)
115
  {
116
    table_ref= table_ref->next_name_resolution_table;
117
    assert(table_ref);
118
    set_field_iterator();
119
  }
120
}
121
122
123
const char *Field_iterator_table_ref::table_name()
124
{
125
  if (table_ref->is_natural_join)
126
    return natural_join_it.column_ref()->table_name();
127
128
  assert(!strcmp(table_ref->table_name,
129
                      table_ref->table->s->table_name.str));
130
  return table_ref->table_name;
131
}
132
133
134
const char *Field_iterator_table_ref::db_name()
135
{
136
  if (table_ref->is_natural_join)
137
    return natural_join_it.column_ref()->db_name();
138
139
  /*
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
140
    Test that TableList::db is the same as TableShare::db to
353 by Brian Aker
Moved Field iterator out to its own definition.
141
    ensure consistency. An exception are I_S schema tables, which
142
    are inconsistent in this respect.
143
  */
144
  assert(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
145
              (table_ref->schema_table &&
146
               table_ref->table->s->db.str[0] == 0));
147
148
  return table_ref->db;
149
}
150
151
354 by Brian Aker
Refactor of Table methods.
152
353 by Brian Aker
Moved Field iterator out to its own definition.
153
/*
154
  Create new or return existing column reference to a column of a
155
  natural/using join.
156
157
  SYNOPSIS
158
    Field_iterator_table_ref::get_or_create_column_ref()
159
    parent_table_ref  the parent table reference over which the
160
                      iterator is iterating
161
162
  DESCRIPTION
163
    Create a new natural join column for the current field of the
164
    iterator if no such column was created, or return an already
165
    created natural join column. The former happens for base tables or
166
    views, and the latter for natural/using joins. If a new field is
167
    created, then the field is added to 'parent_table_ref' if it is
168
    given, or to the original table referene of the field if
169
    parent_table_ref == NULL.
170
171
  NOTES
172
    This method is designed so that when a Field_iterator_table_ref
173
    walks through the fields of a table reference, all its fields
174
    are created and stored as follows:
175
    - If the table reference being iterated is a stored table, view or
176
      natural/using join, store all natural join columns in a list
177
      attached to that table reference.
178
    - If the table reference being iterated is a nested join that is
179
      not natural/using join, then do not materialize its result
180
      fields. This is OK because for such table references
181
      Field_iterator_table_ref iterates over the fields of the nested
182
      table references (recursively). In this way we avoid the storage
183
      of unnecessay copies of result columns of nested joins.
184
185
  RETURN
186
    #     Pointer to a column of a natural join (or its operand)
187
    NULL  No memory to allocate the column
188
*/
189
190
Natural_join_column *
191
Field_iterator_table_ref::get_or_create_column_ref(TableList *parent_table_ref)
192
{
193
  Natural_join_column *nj_col;
194
  bool is_created= true;
482 by Brian Aker
Remove uint.
195
  uint32_t field_count=0;
353 by Brian Aker
Moved Field iterator out to its own definition.
196
  TableList *add_table_ref= parent_table_ref ?
197
                             parent_table_ref : table_ref;
198
199
  if (field_it == &table_field_it)
200
  {
201
    /* The field belongs to a stored table. */
202
    Field *tmp_field= table_field_it.field();
203
    nj_col= new Natural_join_column(tmp_field, table_ref);
204
    field_count= table_ref->table->s->fields;
205
  }
206
  else
207
  {
208
    /*
209
      The field belongs to a NATURAL join, therefore the column reference was
210
      already created via one of the two constructor calls above. In this case
211
      we just return the already created column reference.
212
    */
213
    assert(table_ref->is_join_columns_complete);
214
    is_created= false;
215
    nj_col= natural_join_it.column_ref();
216
    assert(nj_col);
217
  }
218
  assert(!nj_col->table_field ||
219
              nj_col->table_ref->table == nj_col->table_field->table);
220
221
  /*
222
    If the natural join column was just created add it to the list of
223
    natural join columns of either 'parent_table_ref' or to the table
224
    reference that directly contains the original field.
225
  */
226
  if (is_created)
227
  {
228
    /* Make sure not all columns were materialized. */
229
    assert(!add_table_ref->is_join_columns_complete);
230
    if (!add_table_ref->join_columns)
231
    {
232
      /* Create a list of natural join columns on demand. */
233
      if (!(add_table_ref->join_columns= new List<Natural_join_column>))
234
        return NULL;
235
      add_table_ref->is_join_columns_complete= false;
236
    }
237
    add_table_ref->join_columns->push_back(nj_col);
238
    /*
239
      If new fields are added to their original table reference, mark if
240
      all fields were added. We do it here as the caller has no easy way
241
      of knowing when to do it.
242
      If the fields are being added to parent_table_ref, then the caller
243
      must take care to mark when all fields are created/added.
244
    */
245
    if (!parent_table_ref &&
246
        add_table_ref->join_columns->elements == field_count)
247
      add_table_ref->is_join_columns_complete= true;
248
  }
249
250
  return nj_col;
251
}
252
253
254
/*
255
  Return an existing reference to a column of a natural/using join.
256
257
  SYNOPSIS
258
    Field_iterator_table_ref::get_natural_column_ref()
259
260
  DESCRIPTION
261
    The method should be called in contexts where it is expected that
262
    all natural join columns are already created, and that the column
263
    being retrieved is a Natural_join_column.
264
265
  RETURN
266
    #     Pointer to a column of a natural join (or its operand)
267
    NULL  No memory to allocate the column
268
*/
269
270
Natural_join_column *
271
Field_iterator_table_ref::get_natural_column_ref()
272
{
273
  Natural_join_column *nj_col;
274
275
  assert(field_it == &natural_join_it);
276
  /*
277
    The field belongs to a NATURAL join, therefore the column reference was
278
    already created via one of the two constructor calls above. In this case
279
    we just return the already created column reference.
280
  */
281
  nj_col= natural_join_it.column_ref();
282
  assert(nj_col &&
283
              (!nj_col->table_field ||
284
               nj_col->table_ref->table == nj_col->table_field->table));
285
  return nj_col;
286
}
287