~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_iterator.cc

  • Committer: Brian Aker
  • Date: 2008-07-08 16:17:31 UTC
  • Revision ID: brian@tangent.org-20080708161731-io36j7igglok79py
DATE cleanup.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
20
 
#include "config.h"
21
 
#include <drizzled/field_iterator.h>
22
 
#include <drizzled/table_list.h>
23
 
#include <drizzled/session.h>
24
 
#include <drizzled/table.h>
25
 
 
26
 
namespace drizzled
27
 
{
28
 
 
29
 
const char *Field_iterator_table::name()
30
 
{
31
 
  return (*ptr)->field_name;
32
 
}
33
 
 
34
 
 
35
 
void Field_iterator_table::set(TableList *table)
36
 
{
37
 
  ptr= table->table->getFields();
38
 
}
39
 
 
40
 
 
41
 
void Field_iterator_table::set_table(Table *table)
42
 
{
43
 
  ptr= table->getFields();
44
 
}
45
 
 
46
 
 
47
 
Item *Field_iterator_table::create_item(Session *session)
48
 
{
49
 
  Select_Lex *select= session->lex->current_select;
50
 
 
51
 
  Item_field *item= new Item_field(session, &select->context, *ptr);
52
 
 
53
 
  return item;
54
 
}
55
 
 
56
 
 
57
 
void Field_iterator_natural_join::set(TableList *table_ref)
58
 
{
59
 
  assert(table_ref->join_columns);
60
 
  column_ref_it.init(*(table_ref->join_columns));
61
 
  cur_column_ref= column_ref_it++;
62
 
}
63
 
 
64
 
 
65
 
void Field_iterator_natural_join::next()
66
 
{
67
 
  cur_column_ref= column_ref_it++;
68
 
  assert(!cur_column_ref || ! cur_column_ref->table_field ||
69
 
              cur_column_ref->table_ref->table ==
70
 
              cur_column_ref->table_field->getTable());
71
 
}
72
 
 
73
 
 
74
 
void Field_iterator_table_ref::set_field_iterator()
75
 
{
76
 
  /*
77
 
    If the table reference we are iterating over is a natural join, or it is
78
 
    an operand of a natural join, and TableList::join_columns contains all
79
 
    the columns of the join operand, then we pick the columns from
80
 
    TableList::join_columns, instead of the  orginial container of the
81
 
    columns of the join operator.
82
 
  */
83
 
  if (table_ref->is_join_columns_complete)
84
 
  {
85
 
    field_it= &natural_join_it;
86
 
  }
87
 
  /* This is a base table or stored view. */
88
 
  else
89
 
  {
90
 
    assert(table_ref->table);
91
 
    field_it= &table_field_it;
92
 
  }
93
 
  field_it->set(table_ref);
94
 
  return;
95
 
}
96
 
 
97
 
 
98
 
void Field_iterator_table_ref::set(TableList *table)
99
 
{
100
 
  assert(table);
101
 
  first_leaf= table->first_leaf_for_name_resolution();
102
 
  last_leaf=  table->last_leaf_for_name_resolution();
103
 
  assert(first_leaf && last_leaf);
104
 
  table_ref= first_leaf;
105
 
  set_field_iterator();
106
 
}
107
 
 
108
 
 
109
 
void Field_iterator_table_ref::next()
110
 
{
111
 
  /* Move to the next field in the current table reference. */
112
 
  field_it->next();
113
 
  /*
114
 
    If all fields of the current table reference are exhausted, move to
115
 
    the next leaf table reference.
116
 
  */
117
 
  if (field_it->end_of_fields() && table_ref != last_leaf)
118
 
  {
119
 
    table_ref= table_ref->next_name_resolution_table;
120
 
    assert(table_ref);
121
 
    set_field_iterator();
122
 
  }
123
 
}
124
 
 
125
 
 
126
 
const char *Field_iterator_table_ref::table_name()
127
 
{
128
 
  if (table_ref->is_natural_join)
129
 
    return natural_join_it.column_ref()->table_name();
130
 
 
131
 
  assert(!strcmp(table_ref->table_name,
132
 
                      table_ref->table->getShare()->getTableName()));
133
 
  return table_ref->table_name;
134
 
}
135
 
 
136
 
 
137
 
const char *Field_iterator_table_ref::db_name()
138
 
{
139
 
  if (table_ref->is_natural_join)
140
 
    return natural_join_it.column_ref()->db_name();
141
 
 
142
 
  /*
143
 
    Test that TableList::db is the same as TableShare::db to
144
 
    ensure consistency. 
145
 
  */
146
 
  assert(!strcmp(table_ref->db, table_ref->table->getShare()->getSchemaName()));
147
 
  return table_ref->db;
148
 
}
149
 
 
150
 
 
151
 
 
152
 
/*
153
 
  Create new or return existing column reference to a column of a
154
 
  natural/using join.
155
 
 
156
 
  SYNOPSIS
157
 
    Field_iterator_table_ref::get_or_create_column_ref()
158
 
    parent_table_ref  the parent table reference over which the
159
 
                      iterator is iterating
160
 
 
161
 
  DESCRIPTION
162
 
    Create a new natural join column for the current field of the
163
 
    iterator if no such column was created, or return an already
164
 
    created natural join column. The former happens for base tables or
165
 
    views, and the latter for natural/using joins. If a new field is
166
 
    created, then the field is added to 'parent_table_ref' if it is
167
 
    given, or to the original table referene of the field if
168
 
    parent_table_ref == NULL.
169
 
 
170
 
  NOTES
171
 
    This method is designed so that when a Field_iterator_table_ref
172
 
    walks through the fields of a table reference, all its fields
173
 
    are created and stored as follows:
174
 
    - If the table reference being iterated is a stored table, view or
175
 
      natural/using join, store all natural join columns in a list
176
 
      attached to that table reference.
177
 
    - If the table reference being iterated is a nested join that is
178
 
      not natural/using join, then do not materialize its result
179
 
      fields. This is OK because for such table references
180
 
      Field_iterator_table_ref iterates over the fields of the nested
181
 
      table references (recursively). In this way we avoid the storage
182
 
      of unnecessay copies of result columns of nested joins.
183
 
 
184
 
  RETURN
185
 
    #     Pointer to a column of a natural join (or its operand)
186
 
    NULL  No memory to allocate the column
187
 
*/
188
 
 
189
 
Natural_join_column *
190
 
Field_iterator_table_ref::get_or_create_column_ref(TableList *parent_table_ref)
191
 
{
192
 
  Natural_join_column *nj_col;
193
 
  bool is_created= true;
194
 
  uint32_t field_count=0;
195
 
  TableList *add_table_ref= parent_table_ref ?
196
 
                             parent_table_ref : table_ref;
197
 
 
198
 
  if (field_it == &table_field_it)
199
 
  {
200
 
    /* The field belongs to a stored table. */
201
 
    Field *tmp_field= table_field_it.field();
202
 
    nj_col= new Natural_join_column(tmp_field, table_ref);
203
 
    field_count= table_ref->table->getShare()->sizeFields();
204
 
  }
205
 
  else
206
 
  {
207
 
    /*
208
 
      The field belongs to a NATURAL join, therefore the column reference was
209
 
      already created via one of the two constructor calls above. In this case
210
 
      we just return the already created column reference.
211
 
    */
212
 
    assert(table_ref->is_join_columns_complete);
213
 
    is_created= false;
214
 
    nj_col= natural_join_it.column_ref();
215
 
    assert(nj_col);
216
 
  }
217
 
  assert(!nj_col->table_field ||
218
 
              nj_col->table_ref->table == nj_col->table_field->getTable());
219
 
 
220
 
  /*
221
 
    If the natural join column was just created add it to the list of
222
 
    natural join columns of either 'parent_table_ref' or to the table
223
 
    reference that directly contains the original field.
224
 
  */
225
 
  if (is_created)
226
 
  {
227
 
    /* Make sure not all columns were materialized. */
228
 
    assert(!add_table_ref->is_join_columns_complete);
229
 
    if (!add_table_ref->join_columns)
230
 
    {
231
 
      /* Create a list of natural join columns on demand. */
232
 
      if (!(add_table_ref->join_columns= new List<Natural_join_column>))
233
 
        return NULL;
234
 
      add_table_ref->is_join_columns_complete= false;
235
 
    }
236
 
    add_table_ref->join_columns->push_back(nj_col);
237
 
    /*
238
 
      If new fields are added to their original table reference, mark if
239
 
      all fields were added. We do it here as the caller has no easy way
240
 
      of knowing when to do it.
241
 
      If the fields are being added to parent_table_ref, then the caller
242
 
      must take care to mark when all fields are created/added.
243
 
    */
244
 
    if (!parent_table_ref &&
245
 
        add_table_ref->join_columns->elements == field_count)
246
 
      add_table_ref->is_join_columns_complete= true;
247
 
  }
248
 
 
249
 
  return nj_col;
250
 
}
251
 
 
252
 
 
253
 
/*
254
 
  Return an existing reference to a column of a natural/using join.
255
 
 
256
 
  SYNOPSIS
257
 
    Field_iterator_table_ref::get_natural_column_ref()
258
 
 
259
 
  DESCRIPTION
260
 
    The method should be called in contexts where it is expected that
261
 
    all natural join columns are already created, and that the column
262
 
    being retrieved is a Natural_join_column.
263
 
 
264
 
  RETURN
265
 
    #     Pointer to a column of a natural join (or its operand)
266
 
    NULL  No memory to allocate the column
267
 
*/
268
 
 
269
 
Natural_join_column *
270
 
Field_iterator_table_ref::get_natural_column_ref()
271
 
{
272
 
  Natural_join_column *nj_col;
273
 
 
274
 
  assert(field_it == &natural_join_it);
275
 
  /*
276
 
    The field belongs to a NATURAL join, therefore the column reference was
277
 
    already created via one of the two constructor calls above. In this case
278
 
    we just return the already created column reference.
279
 
  */
280
 
  nj_col= natural_join_it.column_ref();
281
 
  assert(nj_col &&
282
 
              (!nj_col->table_field ||
283
 
               nj_col->table_ref->table == nj_col->table_field->getTable()));
284
 
  return nj_col;
285
 
}
286
 
 
287
 
} /* namespace drizzled */