~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
2252.1.18 by Olaf van der Spek
Common fwd
30
namespace drizzled {
1054.1.7 by Brian Aker
Refactor TableList methods.
31
1672.3.5 by Brian Aker
This replaces the allocation we do for insert/update.
32
bool TableList::set_insert_values(memory::Root *)
1054.1.7 by Brian Aker
Refactor TableList methods.
33
{
34
  if (table)
35
  {
1672.3.5 by Brian Aker
This replaces the allocation we do for insert/update.
36
    table->insert_values.resize(table->getShare()->rec_buff_length);
1054.1.7 by Brian Aker
Refactor TableList methods.
37
  }
38
39
  return false;
40
}
41
42
bool TableList::is_leaf_for_name_resolution()
43
{
44
  return (is_natural_join || is_join_columns_complete || !nested_join);
45
}
46
47
TableList *TableList::find_underlying_table(Table *table_to_find)
48
{
49
  /* is this real table and table which we are looking for? */
50
  if (table == table_to_find)
51
    return this;
52
53
  return NULL;
54
}
55
1637.1.3 by Brian Aker
This fixes the parser to no longer do the bad syntax around the cross join
56
bool TableList::isCartesian() const
57
{
58
  return false;
59
}
60
1054.1.7 by Brian Aker
Refactor TableList methods.
61
bool TableList::placeholder()
62
{
1225.1.20 by Padraig O'Sullivan
Removed all remnants of schema_table from the TableList class. This cleans up a bunch of code.
63
  return derived || (create && !table->getDBStat()) || !table;
1054.1.7 by Brian Aker
Refactor TableList methods.
64
}
65
66
/*
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.
67
 * The right-most child of a nested table reference is the first
68
 * element in the list of children because the children are inserted
69
 * in reverse order.
70
 */
1054.1.7 by Brian Aker
Refactor TableList methods.
71
TableList *TableList::last_leaf_for_name_resolution()
72
{
73
  TableList *cur_table_ref= this;
2141.3.3 by vjsamuel1990 at gmail
Merge change nested_join_st to NestedJoin
74
  NestedJoin *cur_nested_join;
1054.1.7 by Brian Aker
Refactor TableList methods.
75
76
  if (is_leaf_for_name_resolution())
77
    return this;
78
  assert(nested_join);
79
80
  for (cur_nested_join= nested_join;
81
       cur_nested_join;
82
       cur_nested_join= cur_table_ref->nested_join)
83
  {
2183.2.21 by Olaf van der Spek
Use List::front()
84
    cur_table_ref= &cur_nested_join->join_list.front();
1054.1.7 by Brian Aker
Refactor TableList methods.
85
    /*
86
      If the current nested is a RIGHT JOIN, the operands in
87
      'join_list' are in reverse order, thus the last operand is in the
88
      end of the list.
89
    */
90
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
91
    {
2183.2.13 by Olaf van der Spek
Use List::begin()
92
      List<TableList>::iterator it(cur_nested_join->join_list.begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
93
      TableList *next;
94
      cur_table_ref= it++;
95
      while ((next= it++))
96
        cur_table_ref= next;
97
    }
98
    if (cur_table_ref->is_leaf_for_name_resolution())
99
      break;
100
  }
101
  return cur_table_ref;
102
}
103
104
/*
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.
105
 * The left-most child of a nested table reference is the last element
106
 * in the list of children because the children are inserted in
107
 * reverse order.
108
 */
1054.1.7 by Brian Aker
Refactor TableList methods.
109
TableList *TableList::first_leaf_for_name_resolution()
110
{
111
  TableList *cur_table_ref= NULL;
2141.3.3 by vjsamuel1990 at gmail
Merge change nested_join_st to NestedJoin
112
  NestedJoin *cur_nested_join;
1054.1.7 by Brian Aker
Refactor TableList methods.
113
114
  if (is_leaf_for_name_resolution())
115
    return this;
116
  assert(nested_join);
117
118
  for (cur_nested_join= nested_join;
119
       cur_nested_join;
120
       cur_nested_join= cur_table_ref->nested_join)
121
  {
2183.2.13 by Olaf van der Spek
Use List::begin()
122
    List<TableList>::iterator it(cur_nested_join->join_list.begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
123
    cur_table_ref= it++;
124
    /*
125
      If the current nested join is a RIGHT JOIN, the operands in
126
      'join_list' are in reverse order, thus the first operand is
127
      already at the front of the list. Otherwise the first operand
128
      is in the end of the list of join operands.
129
    */
130
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
131
    {
132
      TableList *next;
133
      while ((next= it++))
134
        cur_table_ref= next;
135
    }
136
    if (cur_table_ref->is_leaf_for_name_resolution())
137
      break;
138
  }
139
  return cur_table_ref;
140
}
141
142
Item_subselect *TableList::containing_subselect()
143
{
144
  return (select_lex ? select_lex->master_unit()->item : 0);
145
}
146
147
bool TableList::process_index_hints(Table *tbl)
148
{
149
  /* initialize the result variables */
150
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
1574 by Brian Aker
Rollup patch for hiding tableshare.
151
    tbl->keys_in_use_for_order_by= tbl->getShare()->keys_in_use;
1054.1.7 by Brian Aker
Refactor TableList methods.
152
153
  /* index hint list processing */
154
  if (index_hints)
155
  {
156
    key_map index_join[INDEX_HINT_FORCE + 1];
157
    key_map index_order[INDEX_HINT_FORCE + 1];
158
    key_map index_group[INDEX_HINT_FORCE + 1];
159
    Index_hint *hint;
160
    int type;
161
    bool have_empty_use_join= false, have_empty_use_order= false,
162
         have_empty_use_group= false;
2183.2.13 by Olaf van der Spek
Use List::begin()
163
    List_iterator <Index_hint> iter(index_hints->begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
164
165
    /* initialize temporary variables used to collect hints of each kind */
166
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
167
    {
168
      index_join[type].reset();
169
      index_order[type].reset();
170
      index_group[type].reset();
171
    }
172
173
    /* iterate over the hints list */
174
    while ((hint= iter++))
175
    {
1527.1.3 by Brian Aker
This is:
176
      uint32_t pos= 0;
1054.1.7 by Brian Aker
Refactor TableList methods.
177
178
      /* process empty USE INDEX () */
179
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
180
      {
181
        if (hint->clause & INDEX_HINT_MASK_JOIN)
182
        {
183
          index_join[hint->type].reset();
184
          have_empty_use_join= true;
185
        }
186
        if (hint->clause & INDEX_HINT_MASK_ORDER)
187
        {
188
          index_order[hint->type].reset();
189
          have_empty_use_order= true;
190
        }
191
        if (hint->clause & INDEX_HINT_MASK_GROUP)
192
        {
193
          index_group[hint->type].reset();
194
          have_empty_use_group= true;
195
        }
196
        continue;
197
      }
198
199
      /*
200
        Check if an index with the given name exists and get his offset in
201
        the keys bitmask for the table
202
      */
1574 by Brian Aker
Rollup patch for hiding tableshare.
203
      if (not tbl->getShare()->doesKeyNameExist(hint->key_name.str, hint->key_name.length, pos))
1054.1.7 by Brian Aker
Refactor TableList methods.
204
      {
205
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
206
        return 1;
207
      }
208
      /* add to the appropriate clause mask */
209
      if (hint->clause & INDEX_HINT_MASK_JOIN)
210
        index_join[hint->type].set(pos);
211
      if (hint->clause & INDEX_HINT_MASK_ORDER)
212
        index_order[hint->type].set(pos);
213
      if (hint->clause & INDEX_HINT_MASK_GROUP)
214
        index_group[hint->type].set(pos);
215
    }
216
217
    /* cannot mix USE INDEX and FORCE INDEX */
218
    if ((index_join[INDEX_HINT_FORCE].any() ||
219
         index_order[INDEX_HINT_FORCE].any() ||
220
         index_group[INDEX_HINT_FORCE].any()) &&
221
        (index_join[INDEX_HINT_USE].any() ||  have_empty_use_join ||
222
         index_order[INDEX_HINT_USE].any() || have_empty_use_order ||
223
         index_group[INDEX_HINT_USE].any() || have_empty_use_group))
224
    {
225
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
226
               index_hint_type_name[INDEX_HINT_FORCE]);
227
      return 1;
228
    }
229
230
    /* process FORCE INDEX as USE INDEX with a flag */
231
    if (index_join[INDEX_HINT_FORCE].any() ||
232
        index_order[INDEX_HINT_FORCE].any() ||
233
        index_group[INDEX_HINT_FORCE].any())
234
    {
235
      tbl->force_index= true;
236
      index_join[INDEX_HINT_USE]|= index_join[INDEX_HINT_FORCE];
237
      index_order[INDEX_HINT_USE]|= index_order[INDEX_HINT_FORCE];
238
      index_group[INDEX_HINT_USE]|= index_group[INDEX_HINT_FORCE];
239
    }
240
241
    /* apply USE INDEX */
242
    if (index_join[INDEX_HINT_USE].any() || have_empty_use_join)
243
      tbl->keys_in_use_for_query&= index_join[INDEX_HINT_USE];
244
    if (index_order[INDEX_HINT_USE].any() || have_empty_use_order)
245
      tbl->keys_in_use_for_order_by&= index_order[INDEX_HINT_USE];
246
    if (index_group[INDEX_HINT_USE].any() || have_empty_use_group)
247
      tbl->keys_in_use_for_group_by&= index_group[INDEX_HINT_USE];
248
249
    /* apply IGNORE INDEX */
250
    key_map_subtract(tbl->keys_in_use_for_query, index_join[INDEX_HINT_IGNORE]);
251
    key_map_subtract(tbl->keys_in_use_for_order_by, index_order[INDEX_HINT_IGNORE]);
252
    key_map_subtract(tbl->keys_in_use_for_group_by, index_group[INDEX_HINT_IGNORE]);
253
  }
254
255
  /* make sure covering_keys don't include indexes disabled with a hint */
256
  tbl->covering_keys&= tbl->keys_in_use_for_query;
257
  return 0;
258
}
259
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.
260
void TableList::print(Session *session, String *str)
1054.1.7 by Brian Aker
Refactor TableList methods.
261
{
262
  if (nested_join)
263
  {
264
    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.
265
    print_join(session, str, &nested_join->join_list);
1054.1.7 by Brian Aker
Refactor TableList methods.
266
    str->append(')');
267
  }
268
  else
269
  {
270
    const char *cmp_name;                         // Name to compare with alias
271
    if (derived)
272
    {
273
      // A derived table
274
      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.
275
      derived->print(str);
1054.1.7 by Brian Aker
Refactor TableList methods.
276
      str->append(')');
277
      cmp_name= "";                               // Force printing of alias
278
    }
279
    else
280
    {
281
      // A normal table
282
      {
283
        str->append_identifier(db, db_length);
284
        str->append('.');
285
      }
1225.1.20 by Padraig O'Sullivan
Removed all remnants of schema_table from the TableList class. This cleans up a bunch of code.
286
      str->append_identifier(table_name, table_name_length);
287
      cmp_name= table_name;
1054.1.7 by Brian Aker
Refactor TableList methods.
288
    }
289
    if (my_strcasecmp(table_alias_charset, cmp_name, alias))
290
    {
291
292
      if (alias && alias[0])
293
      {
294
        str->append(' ');
295
296
        string t_alias(alias);
2246.4.1 by Olaf van der Spek
Use BOOST_FOREACH
297
        transform(t_alias.begin(), t_alias.end(), t_alias.begin(), ::tolower);
1054.1.7 by Brian Aker
Refactor TableList methods.
298
        str->append_identifier(t_alias.c_str(), t_alias.length());
299
      }
300
    }
301
302
    if (index_hints)
303
    {
2183.2.13 by Olaf van der Spek
Use List::begin()
304
      List<Index_hint>::iterator it(index_hints->begin());
2246.4.1 by Olaf van der Spek
Use BOOST_FOREACH
305
      while (Index_hint* hint= it++)
1054.1.7 by Brian Aker
Refactor TableList methods.
306
      {
307
        str->append (STRING_WITH_LEN(" "));
308
        hint->print (session, str);
309
      }
310
    }
311
  }
312
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
313
314
} /* namespace drizzled */