~drizzle-trunk/drizzle/development

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