1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
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.
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.
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
21
#include <drizzled/field_iterator.h>
22
#include <drizzled/table_list.h>
23
#include <drizzled/session.h>
24
#include <drizzled/table.h>
29
const char *Field_iterator_table::name()
31
return (*ptr)->field_name;
35
void Field_iterator_table::set(TableList *table)
37
ptr= table->table->getFields();
41
void Field_iterator_table::set_table(Table *table)
43
ptr= table->getFields();
47
Item *Field_iterator_table::create_item(Session *session)
49
Select_Lex *select= session->lex->current_select;
51
Item_field *item= new Item_field(session, &select->context, *ptr);
57
void Field_iterator_natural_join::set(TableList *table_ref)
59
assert(table_ref->join_columns);
60
column_ref_it.init(*(table_ref->join_columns));
61
cur_column_ref= column_ref_it++;
65
void Field_iterator_natural_join::next()
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());
74
void Field_iterator_table_ref::set_field_iterator()
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.
83
if (table_ref->is_join_columns_complete)
85
field_it= &natural_join_it;
87
/* This is a base table or stored view. */
90
assert(table_ref->table);
91
field_it= &table_field_it;
93
field_it->set(table_ref);
98
void Field_iterator_table_ref::set(TableList *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();
109
void Field_iterator_table_ref::next()
111
/* Move to the next field in the current table reference. */
114
If all fields of the current table reference are exhausted, move to
115
the next leaf table reference.
117
if (field_it->end_of_fields() && table_ref != last_leaf)
119
table_ref= table_ref->next_name_resolution_table;
121
set_field_iterator();
126
const char *Field_iterator_table_ref::table_name()
128
if (table_ref->is_natural_join)
129
return natural_join_it.column_ref()->table_name();
131
assert(!strcmp(table_ref->table_name,
132
table_ref->table->getShare()->getTableName()));
133
return table_ref->table_name;
137
const char *Field_iterator_table_ref::db_name()
139
if (table_ref->is_natural_join)
140
return natural_join_it.column_ref()->db_name();
143
Test that TableList::db is the same as TableShare::db to
146
assert(!strcmp(table_ref->db, table_ref->table->getShare()->getSchemaName()));
147
return table_ref->db;
153
Create new or return existing column reference to a column of a
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
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.
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.
185
# Pointer to a column of a natural join (or its operand)
186
NULL No memory to allocate the column
189
Natural_join_column *
190
Field_iterator_table_ref::get_or_create_column_ref(TableList *parent_table_ref)
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;
198
if (field_it == &table_field_it)
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();
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.
212
assert(table_ref->is_join_columns_complete);
214
nj_col= natural_join_it.column_ref();
217
assert(!nj_col->table_field ||
218
nj_col->table_ref->table == nj_col->table_field->getTable());
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.
227
/* Make sure not all columns were materialized. */
228
assert(!add_table_ref->is_join_columns_complete);
229
if (!add_table_ref->join_columns)
231
/* Create a list of natural join columns on demand. */
232
if (!(add_table_ref->join_columns= new List<Natural_join_column>))
234
add_table_ref->is_join_columns_complete= false;
236
add_table_ref->join_columns->push_back(nj_col);
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.
244
if (!parent_table_ref &&
245
add_table_ref->join_columns->elements == field_count)
246
add_table_ref->is_join_columns_complete= true;
254
Return an existing reference to a column of a natural/using join.
257
Field_iterator_table_ref::get_natural_column_ref()
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.
265
# Pointer to a column of a natural join (or its operand)
266
NULL No memory to allocate the column
269
Natural_join_column *
270
Field_iterator_table_ref::get_natural_column_ref()
272
Natural_join_column *nj_col;
274
assert(field_it == &natural_join_it);
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.
280
nj_col= natural_join_it.column_ref();
282
(!nj_col->table_field ||
283
nj_col->table_ref->table == nj_col->table_field->getTable()));
287
} /* namespace drizzled */