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
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>
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 st_table_share::db to
141
ensure consistency. An exception are I_S schema tables, which
142
are inconsistent in this respect.
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));
148
return table_ref->db;
154
Create new or return existing column reference to a column of a
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
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.
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.
186
# Pointer to a column of a natural join (or its operand)
187
NULL No memory to allocate the column
190
Natural_join_column *
191
Field_iterator_table_ref::get_or_create_column_ref(TableList *parent_table_ref)
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;
199
if (field_it == &table_field_it)
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;
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.
213
assert(table_ref->is_join_columns_complete);
215
nj_col= natural_join_it.column_ref();
218
assert(!nj_col->table_field ||
219
nj_col->table_ref->table == nj_col->table_field->table);
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.
228
/* Make sure not all columns were materialized. */
229
assert(!add_table_ref->is_join_columns_complete);
230
if (!add_table_ref->join_columns)
232
/* Create a list of natural join columns on demand. */
233
if (!(add_table_ref->join_columns= new List<Natural_join_column>))
235
add_table_ref->is_join_columns_complete= false;
237
add_table_ref->join_columns->push_back(nj_col);
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.
245
if (!parent_table_ref &&
246
add_table_ref->join_columns->elements == field_count)
247
add_table_ref->is_join_columns_complete= true;
255
Return an existing reference to a column of a natural/using join.
258
Field_iterator_table_ref::get_natural_column_ref()
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.
266
# Pointer to a column of a natural join (or its operand)
267
NULL No memory to allocate the column
270
Natural_join_column *
271
Field_iterator_table_ref::get_natural_column_ref()
273
Natural_join_column *nj_col;
275
assert(field_it == &natural_join_it);
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.
281
nj_col= natural_join_it.column_ref();
283
(!nj_col->table_field ||
284
nj_col->table_ref->table == nj_col->table_field->table));