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>
26
const char *Field_iterator_table::name()
28
return (*ptr)->field_name;
32
void Field_iterator_table::set(TableList *table)
34
ptr= table->table->field;
38
void Field_iterator_table::set_table(Table *table)
44
Item *Field_iterator_table::create_item(Session *session)
46
Select_Lex *select= session->lex->current_select;
48
Item_field *item= new Item_field(session, &select->context, *ptr);
54
void Field_iterator_natural_join::set(TableList *table_ref)
56
assert(table_ref->join_columns);
57
column_ref_it.init(*(table_ref->join_columns));
58
cur_column_ref= column_ref_it++;
62
void Field_iterator_natural_join::next()
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);
71
void Field_iterator_table_ref::set_field_iterator()
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.
80
if (table_ref->is_join_columns_complete)
82
field_it= &natural_join_it;
84
/* This is a base table or stored view. */
87
assert(table_ref->table);
88
field_it= &table_field_it;
90
field_it->set(table_ref);
95
void Field_iterator_table_ref::set(TableList *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();
106
void Field_iterator_table_ref::next()
108
/* Move to the next field in the current table reference. */
111
If all fields of the current table reference are exhausted, move to
112
the next leaf table reference.
114
if (field_it->end_of_fields() && table_ref != last_leaf)
116
table_ref= table_ref->next_name_resolution_table;
118
set_field_iterator();
123
const char *Field_iterator_table_ref::table_name()
125
if (table_ref->is_natural_join)
126
return natural_join_it.column_ref()->table_name();
128
assert(!strcmp(table_ref->table_name,
129
table_ref->table->s->table_name.str));
130
return table_ref->table_name;
134
const char *Field_iterator_table_ref::db_name()
136
if (table_ref->is_natural_join)
137
return natural_join_it.column_ref()->db_name();
140
Test that TableList::db is the same as TableShare::db to
143
assert(!strcmp(table_ref->db, table_ref->table->s->db.str));
144
return table_ref->db;
150
Create new or return existing column reference to a column of a
154
Field_iterator_table_ref::get_or_create_column_ref()
155
parent_table_ref the parent table reference over which the
156
iterator is iterating
159
Create a new natural join column for the current field of the
160
iterator if no such column was created, or return an already
161
created natural join column. The former happens for base tables or
162
views, and the latter for natural/using joins. If a new field is
163
created, then the field is added to 'parent_table_ref' if it is
164
given, or to the original table referene of the field if
165
parent_table_ref == NULL.
168
This method is designed so that when a Field_iterator_table_ref
169
walks through the fields of a table reference, all its fields
170
are created and stored as follows:
171
- If the table reference being iterated is a stored table, view or
172
natural/using join, store all natural join columns in a list
173
attached to that table reference.
174
- If the table reference being iterated is a nested join that is
175
not natural/using join, then do not materialize its result
176
fields. This is OK because for such table references
177
Field_iterator_table_ref iterates over the fields of the nested
178
table references (recursively). In this way we avoid the storage
179
of unnecessay copies of result columns of nested joins.
182
# Pointer to a column of a natural join (or its operand)
183
NULL No memory to allocate the column
186
Natural_join_column *
187
Field_iterator_table_ref::get_or_create_column_ref(TableList *parent_table_ref)
189
Natural_join_column *nj_col;
190
bool is_created= true;
191
uint32_t field_count=0;
192
TableList *add_table_ref= parent_table_ref ?
193
parent_table_ref : table_ref;
195
if (field_it == &table_field_it)
197
/* The field belongs to a stored table. */
198
Field *tmp_field= table_field_it.field();
199
nj_col= new Natural_join_column(tmp_field, table_ref);
200
field_count= table_ref->table->s->fields;
205
The field belongs to a NATURAL join, therefore the column reference was
206
already created via one of the two constructor calls above. In this case
207
we just return the already created column reference.
209
assert(table_ref->is_join_columns_complete);
211
nj_col= natural_join_it.column_ref();
214
assert(!nj_col->table_field ||
215
nj_col->table_ref->table == nj_col->table_field->table);
218
If the natural join column was just created add it to the list of
219
natural join columns of either 'parent_table_ref' or to the table
220
reference that directly contains the original field.
224
/* Make sure not all columns were materialized. */
225
assert(!add_table_ref->is_join_columns_complete);
226
if (!add_table_ref->join_columns)
228
/* Create a list of natural join columns on demand. */
229
if (!(add_table_ref->join_columns= new List<Natural_join_column>))
231
add_table_ref->is_join_columns_complete= false;
233
add_table_ref->join_columns->push_back(nj_col);
235
If new fields are added to their original table reference, mark if
236
all fields were added. We do it here as the caller has no easy way
237
of knowing when to do it.
238
If the fields are being added to parent_table_ref, then the caller
239
must take care to mark when all fields are created/added.
241
if (!parent_table_ref &&
242
add_table_ref->join_columns->elements == field_count)
243
add_table_ref->is_join_columns_complete= true;
251
Return an existing reference to a column of a natural/using join.
254
Field_iterator_table_ref::get_natural_column_ref()
257
The method should be called in contexts where it is expected that
258
all natural join columns are already created, and that the column
259
being retrieved is a Natural_join_column.
262
# Pointer to a column of a natural join (or its operand)
263
NULL No memory to allocate the column
266
Natural_join_column *
267
Field_iterator_table_ref::get_natural_column_ref()
269
Natural_join_column *nj_col;
271
assert(field_it == &natural_join_it);
273
The field belongs to a NATURAL join, therefore the column reference was
274
already created via one of the two constructor calls above. In this case
275
we just return the already created column reference.
277
nj_col= natural_join_it.column_ref();
279
(!nj_col->table_field ||
280
nj_col->table_ref->table == nj_col->table_field->table));