~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_list.h

  • Committer: Brian Aker
  • Date: 2008-06-29 20:10:28 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: brian@tangent.org-20080629201028-923bdzz0qcjmd6cm
Cleaned up show status.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
20
 
 
21
 
#ifndef DRIZZLED_TABLE_LIST_H
22
 
#define DRIZZLED_TABLE_LIST_H
23
 
 
24
 
#include <drizzled/table.h>
25
 
 
26
 
namespace drizzled
27
 
{
28
 
 
29
 
class Index_hint;
30
 
class COND_EQUAL;
31
 
class Natural_join_column;
32
 
class select_union;
33
 
class Select_Lex_Unit;
34
 
class Select_Lex;
35
 
class Tmp_Table_Param;
36
 
class Item_subselect;
37
 
class Table;
38
 
 
39
 
namespace plugin
40
 
{
41
 
  class StorageEngine;
42
 
}
43
 
 
44
 
struct nested_join_st;
45
 
 
46
 
/**
47
 
 * A Table referenced in the FROM clause.
48
 
 *
49
 
 * These table references can be of several types that correspond to
50
 
 * different SQL elements. Below we list all types of TableLists with
51
 
 * the necessary conditions to determine when a TableList instance
52
 
 * belongs to a certain type.
53
 
 *
54
 
 * 1) table (TableList::view == NULL)
55
 
 *    - base table
56
 
 *    (TableList::derived == NULL)
57
 
 *    - subquery - TableList::table is a temp table
58
 
 *    (TableList::derived != NULL)
59
 
 *    
60
 
 *    @note
61
 
 *
62
 
 *    for schema tables TableList::field_translation may be != NULL
63
 
 *
64
 
 * 2) Was VIEW 
65
 
 * 3) nested table reference (TableList::nested_join != NULL)
66
 
 *     - table sequence - e.g. (t1, t2, t3)
67
 
 *     @todo how to distinguish from a JOIN?
68
 
 *     - general JOIN
69
 
 *     @todo how to distinguish from a table sequence?
70
 
 *     - NATURAL JOIN
71
 
 *     (TableList::natural_join != NULL)
72
 
 *     - JOIN ... USING
73
 
 *     (TableList::join_using_fields != NULL)
74
 
 *     - semi-join
75
 
 */
76
 
class TableList
77
 
{
78
 
public:
79
 
  TableList():
80
 
    next_local(NULL),
81
 
    next_global(NULL),
82
 
    prev_global(NULL),
83
 
    db(NULL),
84
 
    alias(NULL),
85
 
    table_name(NULL),
86
 
    option(NULL),
87
 
    on_expr(NULL),
88
 
    table(NULL),
89
 
    prep_on_expr(NULL),
90
 
    cond_equal(NULL),
91
 
    natural_join(NULL),
92
 
    is_natural_join(false),
93
 
    is_join_columns_complete(false),
94
 
    straight(false),
95
 
    force_index(false),
96
 
    ignore_leaves(false),
97
 
    join_using_fields(NULL),
98
 
    join_columns(NULL),
99
 
    next_name_resolution_table(NULL),
100
 
    index_hints(NULL),
101
 
    derived_result(NULL),
102
 
    derived(NULL),
103
 
    schema_select_lex(NULL),
104
 
    select_lex(NULL),
105
 
    next_leaf(NULL),
106
 
    outer_join(0),
107
 
    db_length(0),
108
 
    table_name_length(0),
109
 
    dep_tables(0),
110
 
    on_expr_dep_tables(0),
111
 
    nested_join(NULL),
112
 
    embedding(NULL),
113
 
    join_list(NULL),
114
 
    db_type(NULL),
115
 
    internal_tmp_table(false),
116
 
    is_alias(false),
117
 
    is_fqtn(false),
118
 
    create(false)
119
 
  {}
120
 
 
121
 
  /**
122
 
   * List of tables local to a subquery (used by SQL_LIST). Considers
123
 
   * views as leaves (unlike 'next_leaf' below). Created at parse time
124
 
   * in Select_Lex::add_table_to_list() -> table_list.link_in_list().
125
 
   */
126
 
  TableList *next_local;
127
 
 
128
 
  /** link in a global list of all queries tables */
129
 
  TableList *next_global; 
130
 
  TableList **prev_global;
131
 
 
132
 
private:
133
 
  char *db;
134
 
 
135
 
public:
136
 
  const char *getSchemaName()
137
 
  {
138
 
    return db;
139
 
  }
140
 
 
141
 
  char **getSchemaNamePtr()
142
 
  {
143
 
    return &db;
144
 
  }
145
 
 
146
 
  void setSchemaName(char *arg)
147
 
  {
148
 
    db= arg;
149
 
  }
150
 
 
151
 
  const char *alias;
152
 
 
153
 
private:
154
 
  char *table_name;
155
 
 
156
 
public:
157
 
  const char *getTableName()
158
 
  {
159
 
    return table_name;
160
 
  }
161
 
 
162
 
  char **getTableNamePtr()
163
 
  {
164
 
    return &table_name;
165
 
  }
166
 
 
167
 
  void setTableName(char *arg)
168
 
  {
169
 
    table_name= arg;
170
 
  }
171
 
 
172
 
  char *option; ///< Used by cache index
173
 
  Item *on_expr; ///< Used with outer join
174
 
  Table *table; ///< opened table
175
 
  /**
176
 
   * The structure of ON expression presented in the member above
177
 
   * can be changed during certain optimizations. This member
178
 
   * contains a snapshot of AND-OR structure of the ON expression
179
 
   * made after permanent transformations of the parse tree, and is
180
 
   * used to restore ON clause before every reexecution of a prepared
181
 
   * statement or stored procedure.
182
 
   */
183
 
  Item *prep_on_expr;
184
 
  COND_EQUAL *cond_equal; ///< Used with outer join
185
 
  /**
186
 
   * During parsing - left operand of NATURAL/USING join where 'this' is
187
 
   * the right operand. After parsing (this->natural_join == this) iff
188
 
   * 'this' represents a NATURAL or USING join operation. Thus after
189
 
   * parsing 'this' is a NATURAL/USING join iff (natural_join != NULL).
190
 
   */
191
 
  TableList *natural_join;
192
 
  /**
193
 
   * True if 'this' represents a nested join that is a NATURAL JOIN.
194
 
   * For one of the operands of 'this', the member 'natural_join' points
195
 
   * to the other operand of 'this'.
196
 
   */
197
 
  bool is_natural_join;
198
 
 
199
 
  /** true if join_columns contains all columns of this table reference. */
200
 
  bool is_join_columns_complete;
201
 
 
202
 
  bool straight; ///< optimize with prev table
203
 
  bool force_index; ///< prefer index over table scan
204
 
  bool ignore_leaves; ///< preload only non-leaf nodes
205
 
 
206
 
  /*
207
 
    is the table a cartesian join, assumption is yes unless "solved"
208
 
  */
209
 
  bool isCartesian() const;
210
 
 
211
 
  /** Field names in a USING clause for JOIN ... USING. */
212
 
  List<String> *join_using_fields;
213
 
  /**
214
 
   * Explicitly store the result columns of either a NATURAL/USING join or
215
 
   * an operand of such a join.
216
 
   */
217
 
  List<Natural_join_column> *join_columns;
218
 
 
219
 
  /**
220
 
   * List of nodes in a nested join tree, that should be considered as
221
 
   * leaves with respect to name resolution. The leaves are: views,
222
 
   * top-most nodes representing NATURAL/USING joins, subqueries, and
223
 
   * base tables. All of these TableList instances contain a
224
 
   * materialized list of columns. The list is local to a subquery.
225
 
   */
226
 
  TableList *next_name_resolution_table;
227
 
  /** Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */
228
 
  List<Index_hint> *index_hints;
229
 
  /**
230
 
   * select_result for derived table to pass it from table creation to table
231
 
   * filling procedure
232
 
   */
233
 
  select_union *derived_result;
234
 
  Select_Lex_Unit *derived; ///< Select_Lex_Unit of derived table */
235
 
  Select_Lex *schema_select_lex;
236
 
  /** link to select_lex where this table was used */
237
 
  Select_Lex *select_lex;
238
 
  /**
239
 
   * List of all base tables local to a subquery including all view
240
 
   * tables. Unlike 'next_local', this in this list views are *not*
241
 
   * leaves. Created in setup_tables() -> make_leaves_list().
242
 
   */
243
 
  TableList *next_leaf;
244
 
  thr_lock_type lock_type;
245
 
  uint32_t outer_join; ///< Which join type
246
 
  size_t db_length;
247
 
  size_t table_name_length;
248
 
 
249
 
  void set_underlying_merge();
250
 
  bool setup_underlying(Session *session);
251
 
 
252
 
  /**
253
 
   * If you change placeholder(), please check the condition in
254
 
   * check_transactional_lock() too.
255
 
   */
256
 
  bool placeholder();
257
 
  /**
258
 
   * Print table as it should be in join list.
259
 
   * 
260
 
   * @param str   string where table should be printed
261
 
   */
262
 
  void print(Session *session, String *str, enum_query_type query_type);
263
 
  /**
264
 
   * Sets insert_values buffer
265
 
   *
266
 
   * @param[in] memory pool for allocating
267
 
   *
268
 
   * @retval
269
 
   *  false - OK
270
 
   * @retval
271
 
   *  true - out of memory
272
 
   */
273
 
  bool set_insert_values(memory::Root *mem_root);
274
 
  /**
275
 
   * Find underlying base tables (TableList) which represent given
276
 
   * table_to_find (Table)
277
 
   *
278
 
   * @param[in] table to find
279
 
   *
280
 
   * @retval
281
 
   *  NULL if table is not found
282
 
   * @retval
283
 
   *  Pointer to found table reference
284
 
   */
285
 
  TableList *find_underlying_table(Table *table);
286
 
  /**
287
 
   * Retrieve the first (left-most) leaf in a nested join tree with
288
 
   * respect to name resolution.
289
 
   *
290
 
   * @details
291
 
   *
292
 
   * Given that 'this' is a nested table reference, recursively walk
293
 
   * down the left-most children of 'this' until we reach a leaf
294
 
   * table reference with respect to name resolution.
295
 
   *
296
 
   * @retval
297
 
   *  If 'this' is a nested table reference - the left-most child of
298
 
   *  the tree rooted in 'this',
299
 
   *  else return 'this'
300
 
   */
301
 
  TableList *first_leaf_for_name_resolution();
302
 
  /**
303
 
   * Retrieve the last (right-most) leaf in a nested join tree with
304
 
   * respect to name resolution.
305
 
   *
306
 
   * @details
307
 
   *
308
 
   * Given that 'this' is a nested table reference, recursively walk
309
 
   * down the right-most children of 'this' until we reach a leaf
310
 
   * table reference with respect to name resolution.
311
 
   *
312
 
   * @retval
313
 
   *  If 'this' is a nested table reference - the right-most child of
314
 
   *  the tree rooted in 'this',
315
 
   *  else 'this'
316
 
   */
317
 
  TableList *last_leaf_for_name_resolution();
318
 
  /**
319
 
   * Test if this is a leaf with respect to name resolution.
320
 
   *
321
 
   * @details
322
 
   * 
323
 
   * A table reference is a leaf with respect to name resolution if
324
 
   * it is either a leaf node in a nested join tree (table, view,
325
 
   * schema table, subquery), or an inner node that represents a
326
 
   * NATURAL/USING join, or a nested join with materialized join
327
 
   * columns.
328
 
   *
329
 
   * @retval
330
 
   *  true if a leaf, false otherwise.
331
 
   */
332
 
  bool is_leaf_for_name_resolution();
333
 
  inline TableList *top_table()
334
 
  { return this; }
335
 
 
336
 
  /**
337
 
   * Return subselect that contains the FROM list this table is taken from
338
 
   *
339
 
   * @retval
340
 
   *  Subselect item for the subquery that contains the FROM list
341
 
   *  this table is taken from if there is any
342
 
   * @retval
343
 
   *  NULL otherwise
344
 
   */
345
 
  Item_subselect *containing_subselect();
346
 
 
347
 
  /**
348
 
   * Compiles the tagged hints list and fills up st_table::keys_in_use_for_query,
349
 
   * st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
350
 
   * st_table::force_index and st_table::covering_keys.
351
 
   *
352
 
   * @param the Table to operate on.
353
 
   *
354
 
   * @details
355
 
   *
356
 
   * The parser collects the index hints for each table in a "tagged list"
357
 
   * (TableList::index_hints). Using the information in this tagged list
358
 
   * this function sets the members Table::keys_in_use_for_query,
359
 
   * Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
360
 
   * Table::force_index and Table::covering_keys.
361
 
   *
362
 
   * Current implementation of the runtime does not allow mixing FORCE INDEX
363
 
   * and USE INDEX, so this is checked here. Then the FORCE INDEX list
364
 
   * (if non-empty) is appended to the USE INDEX list and a flag is set.
365
 
   * 
366
 
   * Multiple hints of the same kind are processed so that each clause
367
 
   * is applied to what is computed in the previous clause.
368
 
   * 
369
 
   * For example:
370
 
   *       USE INDEX (i1) USE INDEX (i2)
371
 
   *    is equivalent to
372
 
   *       USE INDEX (i1,i2)
373
 
   *    and means "consider only i1 and i2".
374
 
   *
375
 
   * Similarly
376
 
   *       USE INDEX () USE INDEX (i1)
377
 
   *    is equivalent to
378
 
   *       USE INDEX (i1)
379
 
   *    and means "consider only the index i1"
380
 
   *
381
 
   * It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
382
 
   * not an error.
383
 
   *
384
 
   * Different kind of hints (USE/FORCE/IGNORE) are processed in the following
385
 
   * order:
386
 
   *    1. All indexes in USE (or FORCE) INDEX are added to the mask.
387
 
   *    2. All IGNORE INDEX
388
 
   *       e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
389
 
   *       as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
390
 
   *       As an optimization if there is a covering index, and we have
391
 
   *       IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
392
 
   *       then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
393
 
   *
394
 
   * @retval
395
 
   *   false no errors found
396
 
   * @retval
397
 
   *   true found and reported an error.
398
 
   */
399
 
  bool process_index_hints(Table *table);
400
 
 
401
 
  friend std::ostream& operator<<(std::ostream& output, const TableList &list)
402
 
  {
403
 
    output << "TableList:(";
404
 
    output << list.db;
405
 
    output << ", ";
406
 
    output << list.table_name;
407
 
    output << ", ";
408
 
    output << list.alias;
409
 
    output << ", ";
410
 
    output << "is_natural_join:" << list.is_natural_join;
411
 
    output << ", ";
412
 
    output << "is_join_columns_complete:" << list.is_join_columns_complete;
413
 
    output << ", ";
414
 
    output << "straight:" << list.straight;
415
 
    output << ", ";
416
 
    output << "force_index" << list.force_index;
417
 
    output << ", ";
418
 
    output << "ignore_leaves:" << list.ignore_leaves;
419
 
    output << ", ";
420
 
    output << "create:" << list.create;
421
 
    output << ", ";
422
 
    output << "outer_join:" << list.outer_join;
423
 
    output << ", ";
424
 
    output << "nested_join:" << list.nested_join;
425
 
    output << ")";
426
 
 
427
 
    return output;  // for multiple << operators.
428
 
  }
429
 
 
430
 
  void setIsAlias(bool in_is_alias)
431
 
  {
432
 
    is_alias= in_is_alias;
433
 
  }
434
 
 
435
 
  void setIsFqtn(bool in_is_fqtn)
436
 
  {
437
 
    is_fqtn= in_is_fqtn;
438
 
  }
439
 
 
440
 
  void setCreate(bool in_create)
441
 
  {
442
 
    create= in_create;
443
 
  }
444
 
 
445
 
  void setInternalTmpTable(bool in_internal_tmp_table)
446
 
  {
447
 
    internal_tmp_table= in_internal_tmp_table;
448
 
  }
449
 
 
450
 
  void setDbType(plugin::StorageEngine *in_db_type)
451
 
  {
452
 
    db_type= in_db_type;
453
 
  }
454
 
 
455
 
  void setJoinList(List<TableList> *in_join_list)
456
 
  {
457
 
    join_list= in_join_list;
458
 
  }
459
 
 
460
 
  void setEmbedding(TableList *in_embedding)
461
 
  {
462
 
    embedding= in_embedding;
463
 
  }
464
 
 
465
 
  void setNestedJoin(nested_join_st *in_nested_join)
466
 
  {
467
 
    nested_join= in_nested_join;
468
 
  }
469
 
 
470
 
  void setDepTables(table_map in_dep_tables)
471
 
  {
472
 
    dep_tables= in_dep_tables;
473
 
  }
474
 
 
475
 
  void setOnExprDepTables(table_map in_on_expr_dep_tables)
476
 
  {
477
 
    on_expr_dep_tables= in_on_expr_dep_tables;
478
 
  }
479
 
 
480
 
  bool getIsAlias() const
481
 
  {
482
 
    return is_alias;
483
 
  }
484
 
 
485
 
  bool getIsFqtn() const
486
 
  {
487
 
    return is_fqtn;
488
 
  }
489
 
 
490
 
  bool isCreate() const
491
 
  {
492
 
    return create;
493
 
  }
494
 
 
495
 
  bool getInternalTmpTable() const
496
 
  {
497
 
    return internal_tmp_table;
498
 
  }
499
 
 
500
 
  plugin::StorageEngine *getDbType() const
501
 
  {
502
 
    return db_type;
503
 
  }
504
 
 
505
 
  TableList *getEmbedding() const
506
 
  {
507
 
    return embedding;
508
 
  }
509
 
 
510
 
  List<TableList> *getJoinList() const
511
 
  {
512
 
    return join_list;
513
 
  }
514
 
 
515
 
  nested_join_st *getNestedJoin() const
516
 
  {
517
 
    return nested_join;
518
 
  }
519
 
 
520
 
  table_map getDepTables() const
521
 
  {
522
 
    return dep_tables;
523
 
  }
524
 
 
525
 
  table_map getOnExprDepTables() const
526
 
  {
527
 
    return on_expr_dep_tables;
528
 
  }
529
 
 
530
 
  void unlock_table_name();
531
 
  void unlock_table_names(TableList *last_table= NULL);
532
 
 
533
 
private:
534
 
 
535
 
  table_map dep_tables; ///< tables the table depends on
536
 
  table_map on_expr_dep_tables; ///< tables on expression depends on
537
 
  nested_join_st *nested_join; ///< if the element is a nested join
538
 
  TableList *embedding; ///< nested join containing the table
539
 
  List<TableList> *join_list; ///< join list the table belongs to
540
 
  plugin::StorageEngine *db_type; ///< table_type for handler
541
 
  char timestamp_buffer[20]; ///< buffer for timestamp (19+1)
542
 
  bool internal_tmp_table;
543
 
  /** true if an alias for this table was specified in the SQL. */
544
 
  bool is_alias;
545
 
 
546
 
  /** 
547
 
   * true if the table is referred to in the statement using a fully
548
 
   * qualified name (<db_name>.<table_name>).
549
 
   */
550
 
  bool is_fqtn;
551
 
  /**
552
 
   * This TableList object corresponds to the table to be created
553
 
   * so it is possible that it does not exist (used in CREATE TABLE
554
 
   * ... SELECT implementation).
555
 
   */
556
 
  bool create;
557
 
 
558
 
};
559
 
 
560
 
void close_thread_tables(Session *session);
561
 
 
562
 
} /* namespace drizzled */
563
 
 
564
 
#endif /* DRIZZLED_TABLE_LIST_H */