~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_iterator.cc

  • Committer: Monty Taylor
  • Date: 2008-10-08 01:10:45 UTC
  • mto: This revision was merged to the branch mainline in revision 491.
  • Revision ID: monty@inaugust.com-20081008011045-zqozbc81f8qhmxok
Get rid of pragma interface/pragma implementation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
10
 
 
11
void Field_iterator_table::set(TableList *table) 
 
12
 
13
  ptr= table->table->field; 
 
14
}
 
15
 
 
16
 
 
17
void Field_iterator_table::set_table(Table *table) 
 
18
 
19
  ptr= table->field; 
 
20
}
 
21
 
 
22
 
 
23
Item *Field_iterator_table::create_item(THD *thd)
 
24
{
 
25
  SELECT_LEX *select= thd->lex->current_select;
 
26
 
 
27
  Item_field *item= new Item_field(thd, &select->context, *ptr);
 
28
 
 
29
#ifdef DEAD_CODE
 
30
 
 
31
  if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
 
32
      !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
 
33
  {
 
34
    select->non_agg_fields.push_back(item);
 
35
    item->marker= select->cur_pos_in_select_list;
 
36
  }
 
37
#endif
 
38
 
 
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
 
 
147
 
 
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;
 
190
  uint32_t field_count=0;
 
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