~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
    bool have_empty_use_join= false, have_empty_use_order= false,
160
         have_empty_use_group= false;
2183.2.13 by Olaf van der Spek
Use List::begin()
161
    List_iterator <Index_hint> iter(index_hints->begin());
1054.1.7 by Brian Aker
Refactor TableList methods.
162
163
    /* initialize temporary variables used to collect hints of each kind */
2318.8.9 by Olaf van der Spek
Use boost::to_upper
164
    for (int type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
1054.1.7 by Brian Aker
Refactor TableList methods.
165
    {
166
      index_join[type].reset();
167
      index_order[type].reset();
168
      index_group[type].reset();
169
    }
170
171
    /* iterate over the hints list */
2318.8.9 by Olaf van der Spek
Use boost::to_upper
172
    while (Index_hint* hint= iter++)
1054.1.7 by Brian Aker
Refactor TableList methods.
173
    {
174
      /* process empty USE INDEX () */
175
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
176
      {
177
        if (hint->clause & INDEX_HINT_MASK_JOIN)
178
        {
179
          index_join[hint->type].reset();
180
          have_empty_use_join= true;
181
        }
182
        if (hint->clause & INDEX_HINT_MASK_ORDER)
183
        {
184
          index_order[hint->type].reset();
185
          have_empty_use_order= true;
186
        }
187
        if (hint->clause & INDEX_HINT_MASK_GROUP)
188
        {
189
          index_group[hint->type].reset();
190
          have_empty_use_group= true;
191
        }
192
        continue;
193
      }
194
195
      /*
196
        Check if an index with the given name exists and get his offset in
197
        the keys bitmask for the table
198
      */
2318.8.9 by Olaf van der Spek
Use boost::to_upper
199
      uint32_t pos= 0;
1574 by Brian Aker
Rollup patch for hiding tableshare.
200
      if (not tbl->getShare()->doesKeyNameExist(hint->key_name.str, hint->key_name.length, pos))
1054.1.7 by Brian Aker
Refactor TableList methods.
201
      {
202
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
203
        return 1;
204
      }
205
      /* add to the appropriate clause mask */
206
      if (hint->clause & INDEX_HINT_MASK_JOIN)
207
        index_join[hint->type].set(pos);
208
      if (hint->clause & INDEX_HINT_MASK_ORDER)
209
        index_order[hint->type].set(pos);
210
      if (hint->clause & INDEX_HINT_MASK_GROUP)
211
        index_group[hint->type].set(pos);
212
    }
213
214
    /* cannot mix USE INDEX and FORCE INDEX */
215
    if ((index_join[INDEX_HINT_FORCE].any() ||
216
         index_order[INDEX_HINT_FORCE].any() ||
217
         index_group[INDEX_HINT_FORCE].any()) &&
218
        (index_join[INDEX_HINT_USE].any() ||  have_empty_use_join ||
219
         index_order[INDEX_HINT_USE].any() || have_empty_use_order ||
220
         index_group[INDEX_HINT_USE].any() || have_empty_use_group))
221
    {
222
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
223
               index_hint_type_name[INDEX_HINT_FORCE]);
224
      return 1;
225
    }
226
227
    /* process FORCE INDEX as USE INDEX with a flag */
228
    if (index_join[INDEX_HINT_FORCE].any() ||
229
        index_order[INDEX_HINT_FORCE].any() ||
230
        index_group[INDEX_HINT_FORCE].any())
231
    {
232
      tbl->force_index= true;
233
      index_join[INDEX_HINT_USE]|= index_join[INDEX_HINT_FORCE];
234
      index_order[INDEX_HINT_USE]|= index_order[INDEX_HINT_FORCE];
235
      index_group[INDEX_HINT_USE]|= index_group[INDEX_HINT_FORCE];
236
    }
237
238
    /* apply USE INDEX */
239
    if (index_join[INDEX_HINT_USE].any() || have_empty_use_join)
240
      tbl->keys_in_use_for_query&= index_join[INDEX_HINT_USE];
241
    if (index_order[INDEX_HINT_USE].any() || have_empty_use_order)
242
      tbl->keys_in_use_for_order_by&= index_order[INDEX_HINT_USE];
243
    if (index_group[INDEX_HINT_USE].any() || have_empty_use_group)
244
      tbl->keys_in_use_for_group_by&= index_group[INDEX_HINT_USE];
245
246
    /* apply IGNORE INDEX */
247
    key_map_subtract(tbl->keys_in_use_for_query, index_join[INDEX_HINT_IGNORE]);
248
    key_map_subtract(tbl->keys_in_use_for_order_by, index_order[INDEX_HINT_IGNORE]);
249
    key_map_subtract(tbl->keys_in_use_for_group_by, index_group[INDEX_HINT_IGNORE]);
250
  }
251
252
  /* make sure covering_keys don't include indexes disabled with a hint */
253
  tbl->covering_keys&= tbl->keys_in_use_for_query;
254
  return 0;
255
}
256
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.
257
void TableList::print(Session *session, String *str)
1054.1.7 by Brian Aker
Refactor TableList methods.
258
{
259
  if (nested_join)
260
  {
261
    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.
262
    print_join(session, str, &nested_join->join_list);
1054.1.7 by Brian Aker
Refactor TableList methods.
263
    str->append(')');
264
  }
265
  else
266
  {
267
    const char *cmp_name;                         // Name to compare with alias
268
    if (derived)
269
    {
270
      // A derived table
271
      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.
272
      derived->print(str);
1054.1.7 by Brian Aker
Refactor TableList methods.
273
      str->append(')');
274
      cmp_name= "";                               // Force printing of alias
275
    }
276
    else
277
    {
278
      // A normal table
279
      {
280
        str->append_identifier(db, db_length);
281
        str->append('.');
282
      }
2385.1.5 by Olaf van der Spek
Refactor
283
      str->append_identifier(table_name);
284
      cmp_name= table_name.data();
1054.1.7 by Brian Aker
Refactor TableList methods.
285
    }
286
    if (my_strcasecmp(table_alias_charset, cmp_name, alias))
287
    {
288
289
      if (alias && alias[0])
290
      {
291
        str->append(' ');
292
        string t_alias(alias);
2318.7.21 by Olaf van der Spek
Use boost::to_lower
293
        boost::to_lower(t_alias);
2318.8.1 by Olaf van der Spek
Add data_ref.h
294
        str->append_identifier(t_alias);
1054.1.7 by Brian Aker
Refactor TableList methods.
295
      }
296
    }
297
298
    if (index_hints)
299
    {
2183.2.13 by Olaf van der Spek
Use List::begin()
300
      List<Index_hint>::iterator it(index_hints->begin());
2246.4.1 by Olaf van der Spek
Use BOOST_FOREACH
301
      while (Index_hint* hint= it++)
1054.1.7 by Brian Aker
Refactor TableList methods.
302
      {
2318.8.1 by Olaf van der Spek
Add data_ref.h
303
        str->append(STRING_WITH_LEN(" "));
304
        hint->print(session, str);
1054.1.7 by Brian Aker
Refactor TableList methods.
305
      }
306
    }
307
  }
308
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
309
310
} /* namespace drizzled */