~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_iterator.cc

  • Committer: Monty Taylor
  • Date: 2008-08-16 21:06:22 UTC
  • Revision ID: monty@inaugust.com-20080816210622-zpnn13unyinqzn72
Updated po files.

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 <drizzled/server_includes.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
 
const char *Field_iterator_table::name()
27
 
{
28
 
  return (*ptr)->field_name;
29
 
}
30
 
 
31
 
 
32
 
void Field_iterator_table::set(TableList *table)
33
 
{
34
 
  ptr= table->table->field;
35
 
}
36
 
 
37
 
 
38
 
void Field_iterator_table::set_table(Table *table)
39
 
{
40
 
  ptr= table->field;
41
 
}
42
 
 
43
 
 
44
 
Item *Field_iterator_table::create_item(Session *session)
45
 
{
46
 
  SELECT_LEX *select= session->lex->current_select;
47
 
 
48
 
  Item_field *item= new Item_field(session, &select->context, *ptr);
49
 
 
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
 
  /*
140
 
    Test that TableList::db is the same as st_table_share::db to
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
 
 
152
 
 
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;
195
 
  uint32_t field_count=0;
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