~drizzle-trunk/drizzle/development

1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
1
/* Copyright (C) 2009 Sun Microsystems, Inc.
1054.1.7 by Brian Aker
Refactor TableList methods.
2
3
  This program is free software; you can redistribute it and/or modify
4
  it under the terms of the GNU General Public License as published by
5
  the Free Software Foundation; version 2 of the License.
6
7
  This program is distributed in the hope that it will be useful,
8
  but WITHOUT ANY WARRANTY; without even the implied warranty of
9
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
  GNU General Public License for more details.
11
12
  You should have received a copy of the GNU General Public License
13
  along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1054.1.7 by Brian Aker
Refactor TableList methods.
15
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
16
#include <config.h>
1054.1.7 by Brian Aker
Refactor TableList methods.
17
18
#include <string>
19
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
20
#include <drizzled/error.h>
21
#include <drizzled/table_list.h>
22
#include <drizzled/item.h>
23
#include <drizzled/item/field.h>
24
#include <drizzled/nested_join.h>
25
#include <drizzled/sql_lex.h>
26
#include <drizzled/sql_select.h>
1122.2.13 by Monty Taylor
Header cleanup.
27
1054.1.7 by Brian Aker
Refactor TableList methods.
28
using namespace std;
29
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
30
namespace drizzled
31
{
32
1054.1.7 by Brian Aker
Refactor TableList methods.
33
class Item;
34
class Item_field;
35
1672.3.5 by Brian Aker
This replaces the allocation we do for insert/update.
36
bool TableList::set_insert_values(memory::Root *)
1054.1.7 by Brian Aker
Refactor TableList methods.
37
{
38
  if (table)
39
  {
1672.3.5 by Brian Aker
This replaces the allocation we do for insert/update.
40
    table->insert_values.resize(table->getShare()->rec_buff_length);
1054.1.7 by Brian Aker
Refactor TableList methods.
41
  }
42
43
  return false;
44
}
45
46
bool TableList::is_leaf_for_name_resolution()
47
{
48
  return (is_natural_join || is_join_columns_complete || !nested_join);
49
}
50
51
TableList *TableList::find_underlying_table(Table *table_to_find)
52
{
53
  /* is this real table and table which we are looking for? */
54
  if (table == table_to_find)
55
    return this;
56
57
  return NULL;
58
}
59
1637.1.3 by Brian Aker
This fixes the parser to no longer do the bad syntax around the cross join
60
bool TableList::isCartesian() const
61
{
62
  return false;
63
}
64
1054.1.7 by Brian Aker
Refactor TableList methods.
65
bool TableList::placeholder()
66
{
1225.1.20 by Padraig O'Sullivan
Removed all remnants of schema_table from the TableList class. This cleans up a bunch of code.
67
  return derived || (create && !table->getDBStat()) || !table;
1054.1.7 by Brian Aker
Refactor TableList methods.
68
}
69
70
/*
1188.1.2 by Jay Pipes
Style and doxygen cleanup ONLY. Moves method documentation from source into header files. Removes TAB characters and cleans up indentation.
71
 * The right-most child of a nested table reference is the first
72
 * element in the list of children because the children are inserted
73
 * in reverse order.
74
 */
1054.1.7 by Brian Aker
Refactor TableList methods.
75
TableList *TableList::last_leaf_for_name_resolution()
76
{
77
  TableList *cur_table_ref= this;
2141.3.3 by vjsamuel1990 at gmail
Merge change nested_join_st to NestedJoin
78
  NestedJoin *cur_nested_join;
1054.1.7 by Brian Aker
Refactor TableList methods.
79
80
  if (is_leaf_for_name_resolution())
81
    return this;
82
  assert(nested_join);
83
84
  for (cur_nested_join= nested_join;
85
       cur_nested_join;
86
       cur_nested_join= cur_table_ref->nested_join)
87
  {
2183.2.21 by Olaf van der Spek
Use List::front()
88
    cur_table_ref= &cur_nested_join->join_list.front();
1054.1.7 by Brian Aker
Refactor TableList methods.
89
    /*
90
      If the current nested is a RIGHT JOIN, the operands in
91
      'join_list' are in reverse order, thus the last operand is in the
92
      end of the list.
93
    */
94
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
95
    {
2183.2.13 by Olaf van der Spek
Use List::begin()
96
      List<TableList>::iterator it(cur_nested_join->join_list.begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
97
      TableList *next;
98
      cur_table_ref= it++;
99
      while ((next= it++))
100
        cur_table_ref= next;
101
    }
102
    if (cur_table_ref->is_leaf_for_name_resolution())
103
      break;
104
  }
105
  return cur_table_ref;
106
}
107
108
/*
1188.1.2 by Jay Pipes
Style and doxygen cleanup ONLY. Moves method documentation from source into header files. Removes TAB characters and cleans up indentation.
109
 * The left-most child of a nested table reference is the last element
110
 * in the list of children because the children are inserted in
111
 * reverse order.
112
 */
1054.1.7 by Brian Aker
Refactor TableList methods.
113
TableList *TableList::first_leaf_for_name_resolution()
114
{
115
  TableList *cur_table_ref= NULL;
2141.3.3 by vjsamuel1990 at gmail
Merge change nested_join_st to NestedJoin
116
  NestedJoin *cur_nested_join;
1054.1.7 by Brian Aker
Refactor TableList methods.
117
118
  if (is_leaf_for_name_resolution())
119
    return this;
120
  assert(nested_join);
121
122
  for (cur_nested_join= nested_join;
123
       cur_nested_join;
124
       cur_nested_join= cur_table_ref->nested_join)
125
  {
2183.2.13 by Olaf van der Spek
Use List::begin()
126
    List<TableList>::iterator it(cur_nested_join->join_list.begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
127
    cur_table_ref= it++;
128
    /*
129
      If the current nested join is a RIGHT JOIN, the operands in
130
      'join_list' are in reverse order, thus the first operand is
131
      already at the front of the list. Otherwise the first operand
132
      is in the end of the list of join operands.
133
    */
134
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
135
    {
136
      TableList *next;
137
      while ((next= it++))
138
        cur_table_ref= next;
139
    }
140
    if (cur_table_ref->is_leaf_for_name_resolution())
141
      break;
142
  }
143
  return cur_table_ref;
144
}
145
146
Item_subselect *TableList::containing_subselect()
147
{
148
  return (select_lex ? select_lex->master_unit()->item : 0);
149
}
150
151
bool TableList::process_index_hints(Table *tbl)
152
{
153
  /* initialize the result variables */
154
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
1574 by Brian Aker
Rollup patch for hiding tableshare.
155
    tbl->keys_in_use_for_order_by= tbl->getShare()->keys_in_use;
1054.1.7 by Brian Aker
Refactor TableList methods.
156
157
  /* index hint list processing */
158
  if (index_hints)
159
  {
160
    key_map index_join[INDEX_HINT_FORCE + 1];
161
    key_map index_order[INDEX_HINT_FORCE + 1];
162
    key_map index_group[INDEX_HINT_FORCE + 1];
163
    Index_hint *hint;
164
    int type;
165
    bool have_empty_use_join= false, have_empty_use_order= false,
166
         have_empty_use_group= false;
2183.2.13 by Olaf van der Spek
Use List::begin()
167
    List_iterator <Index_hint> iter(index_hints->begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
168
169
    /* initialize temporary variables used to collect hints of each kind */
170
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
171
    {
172
      index_join[type].reset();
173
      index_order[type].reset();
174
      index_group[type].reset();
175
    }
176
177
    /* iterate over the hints list */
178
    while ((hint= iter++))
179
    {
1527.1.3 by Brian Aker
This is:
180
      uint32_t pos= 0;
1054.1.7 by Brian Aker
Refactor TableList methods.
181
182
      /* process empty USE INDEX () */
183
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
184
      {
185
        if (hint->clause & INDEX_HINT_MASK_JOIN)
186
        {
187
          index_join[hint->type].reset();
188
          have_empty_use_join= true;
189
        }
190
        if (hint->clause & INDEX_HINT_MASK_ORDER)
191
        {
192
          index_order[hint->type].reset();
193
          have_empty_use_order= true;
194
        }
195
        if (hint->clause & INDEX_HINT_MASK_GROUP)
196
        {
197
          index_group[hint->type].reset();
198
          have_empty_use_group= true;
199
        }
200
        continue;
201
      }
202
203
      /*
204
        Check if an index with the given name exists and get his offset in
205
        the keys bitmask for the table
206
      */
1574 by Brian Aker
Rollup patch for hiding tableshare.
207
      if (not tbl->getShare()->doesKeyNameExist(hint->key_name.str, hint->key_name.length, pos))
1054.1.7 by Brian Aker
Refactor TableList methods.
208
      {
209
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
210
        return 1;
211
      }
212
      /* add to the appropriate clause mask */
213
      if (hint->clause & INDEX_HINT_MASK_JOIN)
214
        index_join[hint->type].set(pos);
215
      if (hint->clause & INDEX_HINT_MASK_ORDER)
216
        index_order[hint->type].set(pos);
217
      if (hint->clause & INDEX_HINT_MASK_GROUP)
218
        index_group[hint->type].set(pos);
219
    }
220
221
    /* cannot mix USE INDEX and FORCE INDEX */
222
    if ((index_join[INDEX_HINT_FORCE].any() ||
223
         index_order[INDEX_HINT_FORCE].any() ||
224
         index_group[INDEX_HINT_FORCE].any()) &&
225
        (index_join[INDEX_HINT_USE].any() ||  have_empty_use_join ||
226
         index_order[INDEX_HINT_USE].any() || have_empty_use_order ||
227
         index_group[INDEX_HINT_USE].any() || have_empty_use_group))
228
    {
229
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
230
               index_hint_type_name[INDEX_HINT_FORCE]);
231
      return 1;
232
    }
233
234
    /* process FORCE INDEX as USE INDEX with a flag */
235
    if (index_join[INDEX_HINT_FORCE].any() ||
236
        index_order[INDEX_HINT_FORCE].any() ||
237
        index_group[INDEX_HINT_FORCE].any())
238
    {
239
      tbl->force_index= true;
240
      index_join[INDEX_HINT_USE]|= index_join[INDEX_HINT_FORCE];
241
      index_order[INDEX_HINT_USE]|= index_order[INDEX_HINT_FORCE];
242
      index_group[INDEX_HINT_USE]|= index_group[INDEX_HINT_FORCE];
243
    }
244
245
    /* apply USE INDEX */
246
    if (index_join[INDEX_HINT_USE].any() || have_empty_use_join)
247
      tbl->keys_in_use_for_query&= index_join[INDEX_HINT_USE];
248
    if (index_order[INDEX_HINT_USE].any() || have_empty_use_order)
249
      tbl->keys_in_use_for_order_by&= index_order[INDEX_HINT_USE];
250
    if (index_group[INDEX_HINT_USE].any() || have_empty_use_group)
251
      tbl->keys_in_use_for_group_by&= index_group[INDEX_HINT_USE];
252
253
    /* apply IGNORE INDEX */
254
    key_map_subtract(tbl->keys_in_use_for_query, index_join[INDEX_HINT_IGNORE]);
255
    key_map_subtract(tbl->keys_in_use_for_order_by, index_order[INDEX_HINT_IGNORE]);
256
    key_map_subtract(tbl->keys_in_use_for_group_by, index_group[INDEX_HINT_IGNORE]);
257
  }
258
259
  /* make sure covering_keys don't include indexes disabled with a hint */
260
  tbl->covering_keys&= tbl->keys_in_use_for_query;
261
  return 0;
262
}
263
2215.2.1 by Stewart Smith
remove enum_query_type which was effectively unused. It was set to one value once, compared to it once (i.e. always true) and passed around everywhere doing nothing.
264
void TableList::print(Session *session, String *str)
1054.1.7 by Brian Aker
Refactor TableList methods.
265
{
266
  if (nested_join)
267
  {
268
    str->append('(');
2215.2.1 by Stewart Smith
remove enum_query_type which was effectively unused. It was set to one value once, compared to it once (i.e. always true) and passed around everywhere doing nothing.
269
    print_join(session, str, &nested_join->join_list);
1054.1.7 by Brian Aker
Refactor TableList methods.
270
    str->append(')');
271
  }
272
  else
273
  {
274
    const char *cmp_name;                         // Name to compare with alias
275
    if (derived)
276
    {
277
      // A derived table
278
      str->append('(');
2215.2.1 by Stewart Smith
remove enum_query_type which was effectively unused. It was set to one value once, compared to it once (i.e. always true) and passed around everywhere doing nothing.
279
      derived->print(str);
1054.1.7 by Brian Aker
Refactor TableList methods.
280
      str->append(')');
281
      cmp_name= "";                               // Force printing of alias
282
    }
283
    else
284
    {
285
      // A normal table
286
      {
287
        str->append_identifier(db, db_length);
288
        str->append('.');
289
      }
1225.1.20 by Padraig O'Sullivan
Removed all remnants of schema_table from the TableList class. This cleans up a bunch of code.
290
      str->append_identifier(table_name, table_name_length);
291
      cmp_name= table_name;
1054.1.7 by Brian Aker
Refactor TableList methods.
292
    }
293
    if (my_strcasecmp(table_alias_charset, cmp_name, alias))
294
    {
295
296
      if (alias && alias[0])
297
      {
298
        str->append(' ');
299
300
        string t_alias(alias);
301
        transform(t_alias.begin(), t_alias.end(),
302
                  t_alias.begin(), ::tolower);
303
304
        str->append_identifier(t_alias.c_str(), t_alias.length());
305
      }
306
307
    }
308
309
    if (index_hints)
310
    {
2183.2.13 by Olaf van der Spek
Use List::begin()
311
      List<Index_hint>::iterator it(index_hints->begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
312
      Index_hint *hint;
313
314
      while ((hint= it++))
315
      {
316
        str->append (STRING_WITH_LEN(" "));
317
        hint->print (session, str);
318
      }
319
    }
320
  }
321
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
322
323
} /* namespace drizzled */