~ubuntu-branches/ubuntu/trusty/mariadb-5.5/trusty-proposed

« back to all changes in this revision

Viewing changes to sql/table.cc

  • Committer: Package Import Robot
  • Author(s): Otto Kekäläinen
  • Date: 2013-12-22 10:27:05 UTC
  • Revision ID: package-import@ubuntu.com-20131222102705-mndw7s12mz0szrcn
Tags: upstream-5.5.32
Import upstream version 5.5.32

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (c) 2000, 2011, Oracle and/or its affiliates.
 
3
   Copyright (c) 2008-2011 Monty Program Ab
 
4
 
 
5
   This program is free software; you can redistribute it and/or modify
 
6
   it under the terms of the GNU General Public License as published by
 
7
   the Free Software Foundation; version 2 of the License.
 
8
 
 
9
   This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
   GNU General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU General Public License
 
15
   along with this program; if not, write to the Free Software
 
16
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
 
17
 
 
18
 
 
19
/* Some general useful functions */
 
20
 
 
21
#include "my_global.h"                          /* NO_EMBEDDED_ACCESS_CHECKS */
 
22
#include "sql_priv.h"
 
23
#include "unireg.h"                    // REQUIRED: for other includes
 
24
#include "table.h"
 
25
#include "frm_crypt.h"           // get_crypt_for_frm
 
26
#include "key.h"                                // find_ref_key
 
27
#include "sql_table.h"                          // build_table_filename,
 
28
                                                // primary_key_name
 
29
#include "sql_trigger.h"
 
30
#include "sql_parse.h"                          // free_items
 
31
#include "strfunc.h"                            // unhex_type2
 
32
#include "sql_partition.h"       // mysql_unpack_partition,
 
33
                                 // fix_partition_func, partition_info
 
34
#include "sql_acl.h"             // *_ACL, acl_getroot_no_password
 
35
#include "sql_base.h"            // release_table_share
 
36
#include "create_options.h"
 
37
#include <m_ctype.h>
 
38
#include "my_md5.h"
 
39
#include "my_bit.h"
 
40
#include "sql_select.h"
 
41
#include "sql_derived.h"
 
42
#include "mdl.h"                 // MDL_wait_for_graph_visitor
 
43
 
 
44
/* INFORMATION_SCHEMA name */
 
45
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
 
46
 
 
47
/* PERFORMANCE_SCHEMA name */
 
48
LEX_STRING PERFORMANCE_SCHEMA_DB_NAME= {C_STRING_WITH_LEN("performance_schema")};
 
49
 
 
50
/* MYSQL_SCHEMA name */
 
51
LEX_STRING MYSQL_SCHEMA_NAME= {C_STRING_WITH_LEN("mysql")};
 
52
 
 
53
/* GENERAL_LOG name */
 
54
LEX_STRING GENERAL_LOG_NAME= {C_STRING_WITH_LEN("general_log")};
 
55
 
 
56
/* SLOW_LOG name */
 
57
LEX_STRING SLOW_LOG_NAME= {C_STRING_WITH_LEN("slow_log")};
 
58
 
 
59
/* 
 
60
  Keyword added as a prefix when parsing the defining expression for a
 
61
  virtual column read from the column definition saved in the frm file
 
62
*/
 
63
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
 
64
 
 
65
        /* Functions defined in this file */
 
66
 
 
67
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
 
68
                      myf errortype, int errarg);
 
69
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
 
70
                           uchar *head, File file);
 
71
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
 
72
                              uint types, char **names);
 
73
static uint find_field(Field **fields, uchar *record, uint start, uint length);
 
74
 
 
75
inline bool is_system_table_name(const char *name, uint length);
 
76
 
 
77
static ulong get_form_pos(File file, uchar *head);
 
78
 
 
79
/**************************************************************************
 
80
  Object_creation_ctx implementation.
 
81
**************************************************************************/
 
82
 
 
83
Object_creation_ctx *Object_creation_ctx::set_n_backup(THD *thd)
 
84
{
 
85
  Object_creation_ctx *backup_ctx;
 
86
  DBUG_ENTER("Object_creation_ctx::set_n_backup");
 
87
 
 
88
  backup_ctx= create_backup_ctx(thd);
 
89
  change_env(thd);
 
90
 
 
91
  DBUG_RETURN(backup_ctx);
 
92
}
 
93
 
 
94
void Object_creation_ctx::restore_env(THD *thd, Object_creation_ctx *backup_ctx)
 
95
{
 
96
  if (!backup_ctx)
 
97
    return;
 
98
 
 
99
  backup_ctx->change_env(thd);
 
100
 
 
101
  delete backup_ctx;
 
102
}
 
103
 
 
104
/**************************************************************************
 
105
  Default_object_creation_ctx implementation.
 
106
**************************************************************************/
 
107
 
 
108
Default_object_creation_ctx::Default_object_creation_ctx(THD *thd)
 
109
  : m_client_cs(thd->variables.character_set_client),
 
110
    m_connection_cl(thd->variables.collation_connection)
 
111
{ }
 
112
 
 
113
Default_object_creation_ctx::Default_object_creation_ctx(
 
114
  CHARSET_INFO *client_cs, CHARSET_INFO *connection_cl)
 
115
  : m_client_cs(client_cs),
 
116
    m_connection_cl(connection_cl)
 
117
{ }
 
118
 
 
119
Object_creation_ctx *
 
120
Default_object_creation_ctx::create_backup_ctx(THD *thd) const
 
121
{
 
122
  return new Default_object_creation_ctx(thd);
 
123
}
 
124
 
 
125
void Default_object_creation_ctx::change_env(THD *thd) const
 
126
{
 
127
  thd->variables.character_set_client= m_client_cs;
 
128
  thd->variables.collation_connection= m_connection_cl;
 
129
 
 
130
  thd->update_charset();
 
131
}
 
132
 
 
133
/**************************************************************************
 
134
  View_creation_ctx implementation.
 
135
**************************************************************************/
 
136
 
 
137
View_creation_ctx *View_creation_ctx::create(THD *thd)
 
138
{
 
139
  View_creation_ctx *ctx= new (thd->mem_root) View_creation_ctx(thd);
 
140
 
 
141
  return ctx;
 
142
}
 
143
 
 
144
/*************************************************************************/
 
145
 
 
146
View_creation_ctx * View_creation_ctx::create(THD *thd,
 
147
                                              TABLE_LIST *view)
 
148
{
 
149
  View_creation_ctx *ctx= new (thd->mem_root) View_creation_ctx(thd);
 
150
 
 
151
  /* Throw a warning if there is NULL cs name. */
 
152
 
 
153
  if (!view->view_client_cs_name.str ||
 
154
      !view->view_connection_cl_name.str)
 
155
  {
 
156
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
157
                        ER_VIEW_NO_CREATION_CTX,
 
158
                        ER(ER_VIEW_NO_CREATION_CTX),
 
159
                        (const char *) view->db,
 
160
                        (const char *) view->table_name);
 
161
 
 
162
    ctx->m_client_cs= system_charset_info;
 
163
    ctx->m_connection_cl= system_charset_info;
 
164
 
 
165
    return ctx;
 
166
  }
 
167
 
 
168
  /* Resolve cs names. Throw a warning if there is unknown cs name. */
 
169
 
 
170
  bool invalid_creation_ctx;
 
171
 
 
172
  invalid_creation_ctx= resolve_charset(view->view_client_cs_name.str,
 
173
                                        system_charset_info,
 
174
                                        &ctx->m_client_cs);
 
175
 
 
176
  invalid_creation_ctx= resolve_collation(view->view_connection_cl_name.str,
 
177
                                          system_charset_info,
 
178
                                          &ctx->m_connection_cl) ||
 
179
                        invalid_creation_ctx;
 
180
 
 
181
  if (invalid_creation_ctx)
 
182
  {
 
183
    sql_print_warning("View '%s'.'%s': there is unknown charset/collation "
 
184
                      "names (client: '%s'; connection: '%s').",
 
185
                      (const char *) view->db,
 
186
                      (const char *) view->table_name,
 
187
                      (const char *) view->view_client_cs_name.str,
 
188
                      (const char *) view->view_connection_cl_name.str);
 
189
 
 
190
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
191
                        ER_VIEW_INVALID_CREATION_CTX,
 
192
                        ER(ER_VIEW_INVALID_CREATION_CTX),
 
193
                        (const char *) view->db,
 
194
                        (const char *) view->table_name);
 
195
  }
 
196
 
 
197
  return ctx;
 
198
}
 
199
 
 
200
/*************************************************************************/
 
201
 
 
202
/* Get column name from column hash */
 
203
 
 
204
static uchar *get_field_name(Field **buff, size_t *length,
 
205
                             my_bool not_used __attribute__((unused)))
 
206
{
 
207
  *length= (uint) strlen((*buff)->field_name);
 
208
  return (uchar*) (*buff)->field_name;
 
209
}
 
210
 
 
211
 
 
212
/*
 
213
  Returns pointer to '.frm' extension of the file name.
 
214
 
 
215
  SYNOPSIS
 
216
    fn_rext()
 
217
    name       file name
 
218
 
 
219
  DESCRIPTION
 
220
    Checks file name part starting with the rightmost '.' character,
 
221
    and returns it if it is equal to '.frm'. 
 
222
 
 
223
  TODO
 
224
    It is a good idea to get rid of this function modifying the code
 
225
    to garantee that the functions presently calling fn_rext() always
 
226
    get arguments in the same format: either with '.frm' or without '.frm'.
 
227
 
 
228
  RETURN VALUES
 
229
    Pointer to the '.frm' extension. If there is no extension,
 
230
    or extension is not '.frm', pointer at the end of file name.
 
231
*/
 
232
 
 
233
char *fn_rext(char *name)
 
234
{
 
235
  char *res= strrchr(name, '.');
 
236
  if (res && !strcmp(res, reg_ext))
 
237
    return res;
 
238
  return name + strlen(name);
 
239
}
 
240
 
 
241
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
 
242
{
 
243
  DBUG_ASSERT(db != NULL);
 
244
  DBUG_ASSERT(name != NULL);
 
245
 
 
246
  if (is_infoschema_db(db->str, db->length))
 
247
    return TABLE_CATEGORY_INFORMATION;
 
248
 
 
249
  if ((db->length == PERFORMANCE_SCHEMA_DB_NAME.length) &&
 
250
      (my_strcasecmp(system_charset_info,
 
251
                     PERFORMANCE_SCHEMA_DB_NAME.str,
 
252
                     db->str) == 0))
 
253
    return TABLE_CATEGORY_PERFORMANCE;
 
254
 
 
255
  if ((db->length == MYSQL_SCHEMA_NAME.length) &&
 
256
      (my_strcasecmp(system_charset_info,
 
257
                     MYSQL_SCHEMA_NAME.str,
 
258
                     db->str) == 0))
 
259
  {
 
260
    if (is_system_table_name(name->str, name->length))
 
261
      return TABLE_CATEGORY_SYSTEM;
 
262
 
 
263
    if ((name->length == GENERAL_LOG_NAME.length) &&
 
264
        (my_strcasecmp(system_charset_info,
 
265
                       GENERAL_LOG_NAME.str,
 
266
                       name->str) == 0))
 
267
      return TABLE_CATEGORY_LOG;
 
268
 
 
269
    if ((name->length == SLOW_LOG_NAME.length) &&
 
270
        (my_strcasecmp(system_charset_info,
 
271
                       SLOW_LOG_NAME.str,
 
272
                       name->str) == 0))
 
273
      return TABLE_CATEGORY_LOG;
 
274
  }
 
275
 
 
276
  return TABLE_CATEGORY_USER;
 
277
}
 
278
 
 
279
 
 
280
/*
 
281
  Allocate a setup TABLE_SHARE structure
 
282
 
 
283
  SYNOPSIS
 
284
    alloc_table_share()
 
285
    TABLE_LIST          Take database and table name from there
 
286
    key                 Table cache key (db \0 table_name \0...)
 
287
    key_length          Length of key
 
288
 
 
289
  RETURN
 
290
    0  Error (out of memory)
 
291
    #  Share
 
292
*/
 
293
 
 
294
TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
 
295
                               uint key_length)
 
296
{
 
297
  MEM_ROOT mem_root;
 
298
  TABLE_SHARE *share;
 
299
  char *key_buff, *path_buff;
 
300
  char path[FN_REFLEN];
 
301
  uint path_length;
 
302
  DBUG_ENTER("alloc_table_share");
 
303
  DBUG_PRINT("enter", ("table: '%s'.'%s'",
 
304
                       table_list->db, table_list->table_name));
 
305
 
 
306
  path_length= build_table_filename(path, sizeof(path) - 1,
 
307
                                    table_list->db,
 
308
                                    table_list->table_name, "", 0);
 
309
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
310
  if (multi_alloc_root(&mem_root,
 
311
                       &share, sizeof(*share),
 
312
                       &key_buff, key_length,
 
313
                       &path_buff, path_length + 1,
 
314
                       NULL))
 
315
  {
 
316
    bzero((char*) share, sizeof(*share));
 
317
 
 
318
    share->set_table_cache_key(key_buff, key, key_length);
 
319
 
 
320
    share->path.str= path_buff;
 
321
    share->path.length= path_length;
 
322
    strmov(share->path.str, path);
 
323
    share->normalized_path.str=    share->path.str;
 
324
    share->normalized_path.length= path_length;
 
325
 
 
326
    share->set_refresh_version();
 
327
 
 
328
    /*
 
329
      Since alloc_table_share() can be called without any locking (for
 
330
      example, ha_create_table... functions), we do not assign a table
 
331
      map id here.  Instead we assign a value that is not used
 
332
      elsewhere, and then assign a table map id inside open_table()
 
333
      under the protection of the LOCK_open mutex.
 
334
    */
 
335
    share->table_map_id= ~0UL;
 
336
    share->cached_row_logging_check= -1;
 
337
 
 
338
    share->used_tables.empty();
 
339
    share->free_tables.empty();
 
340
    share->m_flush_tickets.empty();
 
341
 
 
342
    memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root));
 
343
    mysql_mutex_init(key_TABLE_SHARE_LOCK_ha_data,
 
344
                     &share->LOCK_ha_data, MY_MUTEX_INIT_FAST);
 
345
  }
 
346
  DBUG_RETURN(share);
 
347
}
 
348
 
 
349
 
 
350
/*
 
351
  Initialize share for temporary tables
 
352
 
 
353
  SYNOPSIS
 
354
    init_tmp_table_share()
 
355
    thd         thread handle
 
356
    share       Share to fill
 
357
    key         Table_cache_key, as generated from create_table_def_key.
 
358
                must start with db name.    
 
359
    key_length  Length of key
 
360
    table_name  Table name
 
361
    path        Path to file (possible in lower case) without .frm
 
362
 
 
363
  NOTES
 
364
    This is different from alloc_table_share() because temporary tables
 
365
    don't have to be shared between threads or put into the table def
 
366
    cache, so we can do some things notable simpler and faster
 
367
 
 
368
    If table is not put in thd->temporary_tables (happens only when
 
369
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
 
370
    use key_length= 0 as neither table_cache_key or key_length will be used).
 
371
*/
 
372
 
 
373
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
 
374
                          uint key_length, const char *table_name,
 
375
                          const char *path)
 
376
{
 
377
  DBUG_ENTER("init_tmp_table_share");
 
378
  DBUG_PRINT("enter", ("table: '%s'.'%s'", key, table_name));
 
379
 
 
380
  bzero((char*) share, sizeof(*share));
 
381
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
382
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
 
383
  share->tmp_table=              INTERNAL_TMP_TABLE;
 
384
  share->db.str=                 (char*) key;
 
385
  share->db.length=              strlen(key);
 
386
  share->table_cache_key.str=    (char*) key;
 
387
  share->table_cache_key.length= key_length;
 
388
  share->table_name.str=         (char*) table_name;
 
389
  share->table_name.length=      strlen(table_name);
 
390
  share->path.str=               (char*) path;
 
391
  share->normalized_path.str=    (char*) path;
 
392
  share->path.length= share->normalized_path.length= strlen(path);
 
393
  share->frm_version=            FRM_VER_TRUE_VARCHAR;
 
394
 
 
395
  share->cached_row_logging_check= -1;
 
396
 
 
397
  /*
 
398
    table_map_id is also used for MERGE tables to suppress repeated
 
399
    compatibility checks.
 
400
  */
 
401
  share->table_map_id= (ulong) thd->query_id;
 
402
 
 
403
  share->used_tables.empty();
 
404
  share->free_tables.empty();
 
405
  share->m_flush_tickets.empty();
 
406
 
 
407
  DBUG_VOID_RETURN;
 
408
}
 
409
 
 
410
 
 
411
/**
 
412
  Release resources (plugins) used by the share and free its memory.
 
413
  TABLE_SHARE is self-contained -- it's stored in its own MEM_ROOT.
 
414
  Free this MEM_ROOT.
 
415
*/
 
416
 
 
417
void TABLE_SHARE::destroy()
 
418
{
 
419
  uint idx;
 
420
  KEY *info_it;
 
421
 
 
422
  /* The mutex is initialized only for shares that are part of the TDC */
 
423
  if (tmp_table == NO_TMP_TABLE)
 
424
    mysql_mutex_destroy(&LOCK_ha_data);
 
425
  my_hash_free(&name_hash);
 
426
 
 
427
  plugin_unlock(NULL, db_plugin);
 
428
  db_plugin= NULL;
 
429
 
 
430
  /* Release fulltext parsers */
 
431
  info_it= key_info;
 
432
  for (idx= keys; idx; idx--, info_it++)
 
433
  {
 
434
    if (info_it->flags & HA_USES_PARSER)
 
435
    {
 
436
      plugin_unlock(NULL, info_it->parser);
 
437
      info_it->flags= 0;
 
438
    }
 
439
  }
 
440
  if (ha_data_destroy)
 
441
  {
 
442
    ha_data_destroy(ha_data);
 
443
    ha_data_destroy= NULL;
 
444
  }
 
445
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
446
  if (ha_part_data_destroy)
 
447
  {
 
448
    ha_part_data_destroy(ha_part_data);
 
449
    ha_part_data_destroy= NULL;
 
450
  }
 
451
#endif /* WITH_PARTITION_STORAGE_ENGINE */
 
452
  /*
 
453
    Make a copy since the share is allocated in its own root,
 
454
    and free_root() updates its argument after freeing the memory.
 
455
  */
 
456
  MEM_ROOT own_root= mem_root;
 
457
  free_root(&own_root, MYF(0));
 
458
}
 
459
 
 
460
/*
 
461
  Free table share and memory used by it
 
462
 
 
463
  SYNOPSIS
 
464
    free_table_share()
 
465
    share               Table share
 
466
*/
 
467
 
 
468
void free_table_share(TABLE_SHARE *share)
 
469
{
 
470
  DBUG_ENTER("free_table_share");
 
471
  DBUG_PRINT("enter", ("table: %s.%s", share->db.str, share->table_name.str));
 
472
  DBUG_ASSERT(share->ref_count == 0);
 
473
 
 
474
  if (share->m_flush_tickets.is_empty())
 
475
  {
 
476
    /*
 
477
      No threads are waiting for this share to be flushed (the
 
478
      share is not old, is for a temporary table, or just nobody
 
479
      happens to be waiting for it). Destroy it.
 
480
    */
 
481
    share->destroy();
 
482
  }
 
483
  else
 
484
  {
 
485
    Wait_for_flush_list::Iterator it(share->m_flush_tickets);
 
486
    Wait_for_flush *ticket;
 
487
    /*
 
488
      We're about to iterate over a list that is used
 
489
      concurrently. Make sure this never happens without a lock.
 
490
    */
 
491
    mysql_mutex_assert_owner(&LOCK_open);
 
492
 
 
493
    while ((ticket= it++))
 
494
      (void) ticket->get_ctx()->m_wait.set_status(MDL_wait::GRANTED);
 
495
    /*
 
496
      If there are threads waiting for this share to be flushed,
 
497
      the last one to receive the notification will destroy the
 
498
      share. At this point the share is removed from the table
 
499
      definition cache, so is OK to proceed here without waiting
 
500
      for this thread to do the work.
 
501
    */
 
502
  }
 
503
  DBUG_VOID_RETURN;
 
504
}
 
505
 
 
506
 
 
507
/**
 
508
  Return TRUE if a table name matches one of the system table names.
 
509
  Currently these are:
 
510
 
 
511
  help_category, help_keyword, help_relation, help_topic,
 
512
  proc, event
 
513
  time_zone, time_zone_leap_second, time_zone_name, time_zone_transition,
 
514
  time_zone_transition_type
 
515
 
 
516
  This function trades accuracy for speed, so may return false
 
517
  positives. Presumably mysql.* database is for internal purposes only
 
518
  and should not contain user tables.
 
519
*/
 
520
 
 
521
inline bool is_system_table_name(const char *name, uint length)
 
522
{
 
523
  CHARSET_INFO *ci= system_charset_info;
 
524
 
 
525
  return (
 
526
          /* mysql.proc table */
 
527
          (length == 4 &&
 
528
           my_tolower(ci, name[0]) == 'p' && 
 
529
           my_tolower(ci, name[1]) == 'r' &&
 
530
           my_tolower(ci, name[2]) == 'o' &&
 
531
           my_tolower(ci, name[3]) == 'c') ||
 
532
 
 
533
          (length > 4 &&
 
534
           (
 
535
            /* one of mysql.help* tables */
 
536
            (my_tolower(ci, name[0]) == 'h' &&
 
537
             my_tolower(ci, name[1]) == 'e' &&
 
538
             my_tolower(ci, name[2]) == 'l' &&
 
539
             my_tolower(ci, name[3]) == 'p') ||
 
540
 
 
541
            /* one of mysql.time_zone* tables */
 
542
            (my_tolower(ci, name[0]) == 't' &&
 
543
             my_tolower(ci, name[1]) == 'i' &&
 
544
             my_tolower(ci, name[2]) == 'm' &&
 
545
             my_tolower(ci, name[3]) == 'e') ||
 
546
 
 
547
            /* mysql.event table */
 
548
            (my_tolower(ci, name[0]) == 'e' &&
 
549
             my_tolower(ci, name[1]) == 'v' &&
 
550
             my_tolower(ci, name[2]) == 'e' &&
 
551
             my_tolower(ci, name[3]) == 'n' &&
 
552
             my_tolower(ci, name[4]) == 't')
 
553
            )
 
554
           )
 
555
         );
 
556
}
 
557
 
 
558
 
 
559
/**
 
560
  Check if a string contains path elements
 
561
*/  
 
562
 
 
563
static bool has_disabled_path_chars(const char *str)
 
564
{
 
565
  for (; *str; str++)
 
566
  {
 
567
    switch (*str) {
 
568
      case FN_EXTCHAR:
 
569
      case '/':
 
570
      case '\\':
 
571
      case '~':
 
572
      case '@':
 
573
        return TRUE;
 
574
    }
 
575
  }
 
576
  return FALSE;
 
577
}
 
578
 
 
579
 
 
580
/*
 
581
  Read table definition from a binary / text based .frm file
 
582
  
 
583
  SYNOPSIS
 
584
  open_table_def()
 
585
  thd           Thread handler
 
586
  share         Fill this with table definition
 
587
  db_flags      Bit mask of the following flags: OPEN_VIEW
 
588
 
 
589
  NOTES
 
590
    This function is called when the table definition is not cached in
 
591
    table_def_cache
 
592
    The data is returned in 'share', which is alloced by
 
593
    alloc_table_share().. The code assumes that share is initialized.
 
594
 
 
595
  RETURN VALUES
 
596
   0    ok
 
597
   1    Error (see open_table_error)
 
598
   2    Error (see open_table_error)
 
599
   3    Wrong data in .frm file
 
600
   4    Error (see open_table_error)
 
601
   5    Error (see open_table_error: charset unavailable)
 
602
   6    Unknown .frm version
 
603
*/
 
604
 
 
605
int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
 
606
{
 
607
  int error, table_type;
 
608
  bool error_given;
 
609
  File file;
 
610
  uchar head[64];
 
611
  char  path[FN_REFLEN];
 
612
  MEM_ROOT **root_ptr, *old_root;
 
613
  DBUG_ENTER("open_table_def");
 
614
  DBUG_PRINT("enter", ("table: '%s'.'%s'  path: '%s'", share->db.str,
 
615
                       share->table_name.str, share->normalized_path.str));
 
616
 
 
617
  error= 1;
 
618
  error_given= 0;
 
619
 
 
620
  strxmov(path, share->normalized_path.str, reg_ext, NullS);
 
621
  if ((file= mysql_file_open(key_file_frm,
 
622
                             path, O_RDONLY | O_SHARE, MYF(0))) < 0)
 
623
  {
 
624
    /*
 
625
      We don't try to open 5.0 unencoded name, if
 
626
      - non-encoded name contains '@' signs, 
 
627
        because '@' can be misinterpreted.
 
628
        It is not clear if '@' is escape character in 5.1,
 
629
        or a normal character in 5.0.
 
630
        
 
631
      - non-encoded db or table name contain "#mysql50#" prefix.
 
632
        This kind of tables must have been opened only by the
 
633
        mysql_file_open() above.
 
634
    */
 
635
    if (has_disabled_path_chars(share->table_name.str) ||
 
636
        has_disabled_path_chars(share->db.str) ||
 
637
        !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
 
638
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
 
639
        !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
 
640
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
 
641
      goto err_not_open;
 
642
 
 
643
    /* Try unencoded 5.0 name */
 
644
    uint length;
 
645
    strxnmov(path, sizeof(path)-1,
 
646
             mysql_data_home, "/", share->db.str, "/",
 
647
             share->table_name.str, reg_ext, NullS);
 
648
    length= unpack_filename(path, path) - reg_ext_length;
 
649
    /*
 
650
      The following is a safety test and should never fail
 
651
      as the old file name should never be longer than the new one.
 
652
    */
 
653
    DBUG_ASSERT(length <= share->normalized_path.length);
 
654
    /*
 
655
      If the old and the new names have the same length,
 
656
      then table name does not have tricky characters,
 
657
      so no need to check the old file name.
 
658
    */
 
659
    if (length == share->normalized_path.length ||
 
660
        ((file= mysql_file_open(key_file_frm,
 
661
                                path, O_RDONLY | O_SHARE, MYF(0))) < 0))
 
662
      goto err_not_open;
 
663
 
 
664
    /* Unencoded 5.0 table name found */
 
665
    path[length]= '\0'; // Remove .frm extension
 
666
    strmov(share->normalized_path.str, path);
 
667
    share->normalized_path.length= length;
 
668
  }
 
669
 
 
670
  error= 4;
 
671
  if (mysql_file_read(file, head, 64, MYF(MY_NABP)))
 
672
    goto err;
 
673
 
 
674
  if (head[0] == (uchar) 254 && head[1] == 1)
 
675
  {
 
676
    if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
 
677
        (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
 
678
    {
 
679
      /* Open view only */
 
680
      if (db_flags & OPEN_VIEW_ONLY)
 
681
      {
 
682
        error_given= 1;
 
683
        goto err;
 
684
      }
 
685
      table_type= 1;
 
686
    }
 
687
    else
 
688
    {
 
689
      error= 6;                                 // Unkown .frm version
 
690
      goto err;
 
691
    }
 
692
  }
 
693
  else if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0)
 
694
  {
 
695
    error= 5;
 
696
    if (memcmp(head+5,"VIEW",4) == 0)
 
697
    {
 
698
      share->is_view= 1;
 
699
      if (db_flags & OPEN_VIEW)
 
700
        error= 0;
 
701
    }
 
702
    goto err;
 
703
  }
 
704
  else
 
705
    goto err;
 
706
 
 
707
  /* No handling of text based files yet */
 
708
  if (table_type == 1)
 
709
  {
 
710
    root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
 
711
    old_root= *root_ptr;
 
712
    *root_ptr= &share->mem_root;
 
713
    error= open_binary_frm(thd, share, head, file);
 
714
    *root_ptr= old_root;
 
715
    error_given= 1;
 
716
  }
 
717
 
 
718
  share->table_category= get_table_category(& share->db, & share->table_name);
 
719
 
 
720
  if (!error)
 
721
    thd->status_var.opened_shares++;
 
722
 
 
723
err:
 
724
  mysql_file_close(file, MYF(MY_WME));
 
725
 
 
726
err_not_open:
 
727
  if (error && !error_given)
 
728
  {
 
729
    share->error= error;
 
730
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
731
  }
 
732
 
 
733
  DBUG_RETURN(error);
 
734
}
 
735
 
 
736
 
 
737
/*
 
738
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
 
739
*/
 
740
 
 
741
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
 
742
                           File file)
 
743
{
 
744
  int error, errarg= 0;
 
745
  uint new_frm_ver, field_pack_length, new_field_pack_flag;
 
746
  uint interval_count, interval_parts, read_length, int_length;
 
747
  uint db_create_options, keys, key_parts, n_length;
 
748
  uint key_info_length, com_length, null_bit_pos;
 
749
  uint extra_rec_buf_length;
 
750
  uint i,j;
 
751
  bool use_hash;
 
752
  char *keynames, *names, *comment_pos;
 
753
  uchar forminfo[288];
 
754
  uchar *record;
 
755
  uchar *disk_buff, *strpos, *null_flags, *null_pos;
 
756
  ulong pos, record_offset;
 
757
  ulong *rec_per_key= NULL;
 
758
  ulong rec_buff_length;
 
759
  handler *handler_file= 0;
 
760
  KEY   *keyinfo;
 
761
  KEY_PART_INFO *key_part= NULL;
 
762
  SQL_CRYPT *crypted=0;
 
763
  Field  **field_ptr, *reg_field;
 
764
  const char **interval_array;
 
765
  enum legacy_db_type legacy_db_type;
 
766
  my_bitmap_map *bitmaps;
 
767
  bool null_bits_are_used;
 
768
  uint vcol_screen_length, UNINIT_VAR(options_len);
 
769
  char *vcol_screen_pos;
 
770
  uchar *UNINIT_VAR(options);
 
771
  uchar *extra_segment_buff= 0;
 
772
  KEY first_keyinfo;
 
773
  uint len;
 
774
  KEY_PART_INFO *first_key_part= NULL;
 
775
  uint ext_key_parts= 0;
 
776
  uint first_key_parts= 0;
 
777
  keyinfo= &first_keyinfo;
 
778
  share->ext_key_parts= 0;
 
779
  DBUG_ENTER("open_binary_frm");
 
780
 
 
781
  new_field_pack_flag= head[27];
 
782
  new_frm_ver= (head[2] - FRM_VER);
 
783
  field_pack_length= new_frm_ver < 2 ? 11 : 17;
 
784
  disk_buff= 0;
 
785
 
 
786
  error= 3;
 
787
  /* Position of the form in the form file. */
 
788
  if (!(pos= get_form_pos(file, head)))
 
789
    goto err;                                   /* purecov: inspected */
 
790
 
 
791
  mysql_file_seek(file,pos,MY_SEEK_SET,MYF(0));
 
792
  if (mysql_file_read(file, forminfo,288,MYF(MY_NABP)))
 
793
    goto err;
 
794
  share->frm_version= head[2];
 
795
  /*
 
796
    Check if .frm file created by MySQL 5.0. In this case we want to
 
797
    display CHAR fields as CHAR and not as VARCHAR.
 
798
    We do it this way as we want to keep the old frm version to enable
 
799
    MySQL 4.1 to read these files.
 
800
  */
 
801
  if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
 
802
    share->frm_version= FRM_VER_TRUE_VARCHAR;
 
803
 
 
804
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
805
  /*
 
806
    Yuck! Double-bad. Doesn't work with dynamic engine codes.
 
807
    And doesn't lock the plugin. Fixed in 10.0.4
 
808
  */
 
809
  compile_time_assert(MYSQL_VERSION_ID < 100000);
 
810
  if (*(head+61) &&
 
811
      !(share->default_part_db_type= 
 
812
        ha_checktype(thd, (enum legacy_db_type) (uint) *(head+61), 1, 0)))
 
813
    goto err;
 
814
  DBUG_PRINT("info", ("default_part_db_type = %u", head[61]));
 
815
#endif
 
816
  legacy_db_type= (enum legacy_db_type) (uint) *(head+3);
 
817
  DBUG_ASSERT(share->db_plugin == NULL);
 
818
  /*
 
819
    if the storage engine is dynamic, no point in resolving it by its
 
820
    dynamically allocated legacy_db_type. We will resolve it later by name.
 
821
  */
 
822
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
 
823
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
 
824
    share->db_plugin= ha_lock_engine(NULL, 
 
825
                                     ha_checktype(thd, legacy_db_type, 0, 0));
 
826
  share->db_create_options= db_create_options= uint2korr(head+30);
 
827
  share->db_options_in_use= share->db_create_options;
 
828
  share->mysql_version= uint4korr(head+51);
 
829
  share->null_field_first= 0;
 
830
  if (!head[32])                                // New frm file in 3.23
 
831
  {
 
832
    share->avg_row_length= uint4korr(head+34);
 
833
    share->transactional= (ha_choice) (head[39] & 3);
 
834
    share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
 
835
    share->row_type= (row_type) head[40];
 
836
    share->table_charset= get_charset((((uint) head[41]) << 8) + 
 
837
                                        (uint) head[38],MYF(0));
 
838
    share->null_field_first= 1;
 
839
  }
 
840
  if (!share->table_charset)
 
841
  {
 
842
    /* unknown charset in head[38] or pre-3.23 frm */
 
843
    if (use_mb(default_charset_info))
 
844
    {
 
845
      /* Warn that we may be changing the size of character columns */
 
846
      sql_print_warning("'%s' had no or invalid character set, "
 
847
                        "and default character set is multi-byte, "
 
848
                        "so character column sizes may have changed",
 
849
                        share->path.str);
 
850
    }
 
851
    share->table_charset= default_charset_info;
 
852
  }
 
853
  share->db_record_offset= 1;
 
854
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
 
855
    share->blob_ptr_size= portable_sizeof_char_ptr;
 
856
  error=4;
 
857
  share->max_rows= uint4korr(head+18);
 
858
  share->min_rows= uint4korr(head+22);
 
859
 
 
860
  /* Read keyinformation */
 
861
  key_info_length= (uint) uint2korr(head+28);
 
862
  mysql_file_seek(file, (ulong) uint2korr(head+6), MY_SEEK_SET, MYF(0));
 
863
  if (read_string(file,(uchar**) &disk_buff,key_info_length))
 
864
    goto err;                                   /* purecov: inspected */
 
865
  if (disk_buff[0] & 0x80)
 
866
  {
 
867
    share->keys=      keys=      (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
 
868
    share->key_parts= key_parts= uint2korr(disk_buff+2);
 
869
  }
 
870
  else
 
871
  {
 
872
    share->keys=      keys=      disk_buff[0];
 
873
    share->key_parts= key_parts= disk_buff[1];
 
874
  }
 
875
  share->keys_for_keyread.init(0);
 
876
  share->keys_in_use.init(keys);
 
877
 
 
878
  /*
 
879
    At this point we don't have enough information read from the frm file
 
880
    to get a proper handlerton for the interesting engine in order to get
 
881
    properties of this engine.
 
882
  */   
 
883
  /* Currently only InnoDB can use extended keys */
 
884
  share->set_use_ext_keys_flag(legacy_db_type == DB_TYPE_INNODB);
 
885
 
 
886
  len= (uint) uint2korr(disk_buff+4);
 
887
  if (!keys)
 
888
  {  
 
889
    if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, len)))
 
890
      goto err;
 
891
    bzero((char*) keyinfo, len);
 
892
    key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
 
893
  }
 
894
  strpos= disk_buff+6;
 
895
 
 
896
  /*
 
897
    If share->use_ext_keys is set to TRUE we assume that any key
 
898
    can be extended by the components of the primary key whose
 
899
    definition is read first from the frm file.
 
900
    For each key only those fields of the assumed primary key are
 
901
    added that are not included in the proper key definition. 
 
902
    If after all it turns out that there is no primary key the
 
903
    added components are removed from each key.
 
904
 
 
905
    When in the future we support others schemes of extending of
 
906
    secondary keys with components of the primary key we'll have
 
907
    to change the type of this flag for an enumeration type.                 
 
908
  */   
 
909
 
 
910
  for (i=0 ; i < keys ; i++, keyinfo++)
 
911
  {
 
912
    if (new_frm_ver >= 3)
 
913
    {
 
914
      keyinfo->flags=      (uint) uint2korr(strpos) ^ HA_NOSAME;
 
915
      keyinfo->key_length= (uint) uint2korr(strpos+2);
 
916
      keyinfo->key_parts=  (uint) strpos[4];
 
917
      keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
 
918
      keyinfo->block_size= uint2korr(strpos+6);
 
919
      strpos+=8;
 
920
    }
 
921
    else
 
922
    {
 
923
      keyinfo->flags=    ((uint) strpos[0]) ^ HA_NOSAME;
 
924
      keyinfo->key_length= (uint) uint2korr(strpos+1);
 
925
      keyinfo->key_parts=  (uint) strpos[3];
 
926
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
927
      strpos+=4;
 
928
    }
 
929
 
 
930
    if (i == 0)
 
931
    {
 
932
      ext_key_parts= key_parts +
 
933
                     (share->use_ext_keys ? first_keyinfo.key_parts*(keys-1) : 0); 
 
934
    
 
935
      n_length=keys * sizeof(KEY) + ext_key_parts * sizeof(KEY_PART_INFO);
 
936
      if (!(keyinfo= (KEY*) alloc_root(&share->mem_root,
 
937
                                       n_length + len)))
 
938
        goto err;                                   /* purecov: inspected */
 
939
      bzero((char*) keyinfo,n_length);
 
940
      share->key_info= keyinfo;
 
941
      key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo + keys);
 
942
 
 
943
      if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
944
                                             sizeof(ulong) * ext_key_parts)))
 
945
        goto err;
 
946
      first_key_part= key_part;
 
947
      first_key_parts= first_keyinfo.key_parts;
 
948
      keyinfo->flags= first_keyinfo.flags;
 
949
      keyinfo->key_length= first_keyinfo.key_length;
 
950
      keyinfo->key_parts= first_keyinfo.key_parts;
 
951
      keyinfo->algorithm= first_keyinfo.algorithm;
 
952
      if (new_frm_ver >= 3)
 
953
        keyinfo->block_size= first_keyinfo.block_size;
 
954
    }
 
955
 
 
956
    keyinfo->key_part=   key_part;
 
957
    keyinfo->rec_per_key= rec_per_key;
 
958
    for (j=keyinfo->key_parts ; j-- ; key_part++)
 
959
    {
 
960
      *rec_per_key++=0;
 
961
      key_part->fieldnr=        (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
 
962
      key_part->offset= (uint) uint2korr(strpos+2)-1;
 
963
      key_part->key_type=       (uint) uint2korr(strpos+5);
 
964
      // key_part->field=       (Field*) 0;     // Will be fixed later
 
965
      if (new_frm_ver >= 1)
 
966
      {
 
967
        key_part->key_part_flag= *(strpos+4);
 
968
        key_part->length=       (uint) uint2korr(strpos+7);
 
969
        strpos+=9;
 
970
      }
 
971
      else
 
972
      {
 
973
        key_part->length=       *(strpos+4);
 
974
        key_part->key_part_flag=0;
 
975
        if (key_part->length > 128)
 
976
        {
 
977
          key_part->length&=127;                /* purecov: inspected */
 
978
          key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
 
979
        }
 
980
        strpos+=7;
 
981
      }
 
982
      key_part->store_length=key_part->length;
 
983
    }
 
984
    keyinfo->ext_key_parts= keyinfo->key_parts;
 
985
    keyinfo->ext_key_flags= keyinfo->flags;
 
986
    keyinfo->ext_key_part_map= 0;
 
987
    if (share->use_ext_keys && i)
 
988
    {
 
989
      keyinfo->ext_key_part_map= 0;
 
990
      for (j= 0; 
 
991
           j < first_key_parts && keyinfo->ext_key_parts < MAX_REF_PARTS;
 
992
           j++)
 
993
      {
 
994
        uint key_parts= keyinfo->key_parts;
 
995
        KEY_PART_INFO* curr_key_part= keyinfo->key_part;
 
996
        KEY_PART_INFO* curr_key_part_end= curr_key_part+key_parts;
 
997
        for ( ; curr_key_part < curr_key_part_end; curr_key_part++)
 
998
        {
 
999
          if (curr_key_part->fieldnr == first_key_part[j].fieldnr)
 
1000
            break;
 
1001
        }
 
1002
        if (curr_key_part == curr_key_part_end)
 
1003
        {
 
1004
          *key_part++= first_key_part[j];
 
1005
          *rec_per_key++= 0;
 
1006
          keyinfo->ext_key_parts++;
 
1007
          keyinfo->ext_key_part_map|= 1 << j;
 
1008
        }
 
1009
      }
 
1010
      if (j == first_key_parts)
 
1011
        keyinfo->ext_key_flags= keyinfo->flags | HA_EXT_NOSAME;
 
1012
    }
 
1013
    share->ext_key_parts+= keyinfo->ext_key_parts;  
 
1014
  }
 
1015
  keynames=(char*) key_part;
 
1016
  strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
 
1017
 
 
1018
  //reading index comments
 
1019
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
 
1020
  {
 
1021
    if (keyinfo->flags & HA_USES_COMMENT)
 
1022
    {
 
1023
      keyinfo->comment.length= uint2korr(strpos);
 
1024
      keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
 
1025
                                         keyinfo->comment.length);
 
1026
      strpos+= 2 + keyinfo->comment.length;
 
1027
    } 
 
1028
    DBUG_ASSERT(test(keyinfo->flags & HA_USES_COMMENT) == 
 
1029
               (keyinfo->comment.length > 0));
 
1030
  }
 
1031
 
 
1032
  share->reclength = uint2korr((head+16));
 
1033
  share->stored_rec_length= share->reclength;
 
1034
  if (*(head+26) == 1)
 
1035
    share->system= 1;                           /* one-record-database */
 
1036
#ifdef HAVE_CRYPTED_FRM
 
1037
  else if (*(head+26) == 2)
 
1038
  {
 
1039
    crypted= get_crypt_for_frm();
 
1040
    share->crypted= 1;
 
1041
  }
 
1042
#endif
 
1043
 
 
1044
  record_offset= (ulong) (uint2korr(head+6)+
 
1045
                          ((uint2korr(head+14) == 0xffff ?
 
1046
                            uint4korr(head+47) : uint2korr(head+14))));
 
1047
 
 
1048
  if ((n_length= uint4korr(head+55)))
 
1049
  {
 
1050
    /* Read extra data segment */
 
1051
    uchar *next_chunk, *buff_end;
 
1052
    DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
 
1053
    if (!(extra_segment_buff= (uchar*) my_malloc(n_length + 1, MYF(MY_WME))))
 
1054
      goto err;
 
1055
    next_chunk= extra_segment_buff;
 
1056
    if (mysql_file_pread(file, extra_segment_buff,
 
1057
                         n_length, record_offset + share->reclength,
 
1058
                         MYF(MY_NABP)))
 
1059
    {
 
1060
      goto err;
 
1061
    }
 
1062
    share->connect_string.length= uint2korr(next_chunk);
 
1063
    if (!(share->connect_string.str= strmake_root(&share->mem_root,
 
1064
                                                  (char*) next_chunk + 2,
 
1065
                                                  share->connect_string.
 
1066
                                                  length)))
 
1067
    {
 
1068
      goto err;
 
1069
    }
 
1070
    next_chunk+= share->connect_string.length + 2;
 
1071
    buff_end= extra_segment_buff + n_length;
 
1072
    if (next_chunk + 2 < buff_end)
 
1073
    {
 
1074
      uint str_db_type_length= uint2korr(next_chunk);
 
1075
      LEX_STRING name;
 
1076
      name.str= (char*) next_chunk + 2;
 
1077
      name.length= str_db_type_length;
 
1078
 
 
1079
      plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
 
1080
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
 
1081
      {
 
1082
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
 
1083
            legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
 
1084
            legacy_db_type != ha_legacy_type(
 
1085
                plugin_data(tmp_plugin, handlerton *)))
 
1086
        {
 
1087
          /* bad file, legacy_db_type did not match the name */
 
1088
          goto err;
 
1089
        }
 
1090
        /*
 
1091
          tmp_plugin is locked with a local lock.
 
1092
          we unlock the old value of share->db_plugin before
 
1093
          replacing it with a globally locked version of tmp_plugin
 
1094
        */
 
1095
        plugin_unlock(NULL, share->db_plugin);
 
1096
        share->db_plugin= my_plugin_lock(NULL, tmp_plugin);
 
1097
        DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
 
1098
                            str_db_type_length, next_chunk + 2,
 
1099
                            ha_legacy_type(share->db_type())));
 
1100
      }
 
1101
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
1102
      else if (str_db_type_length == 9 &&
 
1103
               !strncmp((char *) next_chunk + 2, "partition", 9))
 
1104
      {
 
1105
        /*
 
1106
          Use partition handler
 
1107
          tmp_plugin is locked with a local lock.
 
1108
          we unlock the old value of share->db_plugin before
 
1109
          replacing it with a globally locked version of tmp_plugin
 
1110
        */
 
1111
        /* Check if the partitioning engine is ready */
 
1112
        if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN))
 
1113
        {
 
1114
          error= 8;
 
1115
          my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
 
1116
                   "--skip-partition");
 
1117
          goto err;
 
1118
        }
 
1119
        plugin_unlock(NULL, share->db_plugin);
 
1120
        share->db_plugin= ha_lock_engine(NULL, partition_hton);
 
1121
        DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
 
1122
                            str_db_type_length, next_chunk + 2,
 
1123
                            ha_legacy_type(share->db_type())));
 
1124
      }
 
1125
#endif
 
1126
      else if (!tmp_plugin)
 
1127
      {
 
1128
        /* purecov: begin inspected */
 
1129
        error= 8;
 
1130
        name.str[name.length]=0;
 
1131
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
 
1132
        goto err;
 
1133
        /* purecov: end */
 
1134
      }
 
1135
      next_chunk+= str_db_type_length + 2;
 
1136
    }
 
1137
    if (next_chunk + 5 < buff_end)
 
1138
    {
 
1139
      uint32 partition_info_str_len = uint4korr(next_chunk);
 
1140
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
1141
      if ((share->partition_info_buffer_size=
 
1142
             share->partition_info_str_len= partition_info_str_len))
 
1143
      {
 
1144
        if (!(share->partition_info_str= (char*)
 
1145
              memdup_root(&share->mem_root, next_chunk + 4,
 
1146
                          partition_info_str_len + 1)))
 
1147
        {
 
1148
          goto err;
 
1149
        }
 
1150
      }
 
1151
#else
 
1152
      if (partition_info_str_len)
 
1153
      {
 
1154
        DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
 
1155
        goto err;
 
1156
      }
 
1157
#endif
 
1158
      next_chunk+= 5 + partition_info_str_len;
 
1159
    }
 
1160
    if (share->mysql_version >= 50110 && next_chunk < buff_end)
 
1161
    {
 
1162
      /* New auto_partitioned indicator introduced in 5.1.11 */
 
1163
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
1164
      share->auto_partitioned= *next_chunk;
 
1165
#endif
 
1166
      next_chunk++;
 
1167
    }
 
1168
    keyinfo= share->key_info;
 
1169
    for (i= 0; i < keys; i++, keyinfo++)
 
1170
    {
 
1171
      if (keyinfo->flags & HA_USES_PARSER)
 
1172
      {
 
1173
        LEX_STRING parser_name;
 
1174
        if (next_chunk >= buff_end)
 
1175
        {
 
1176
          DBUG_PRINT("error",
 
1177
                     ("fulltext key uses parser that is not defined in .frm"));
 
1178
          goto err;
 
1179
        }
 
1180
        parser_name.str= (char*) next_chunk;
 
1181
        parser_name.length= strlen((char*) next_chunk);
 
1182
        next_chunk+= parser_name.length + 1;
 
1183
        keyinfo->parser= my_plugin_lock_by_name(NULL, &parser_name,
 
1184
                                                MYSQL_FTPARSER_PLUGIN);
 
1185
        if (! keyinfo->parser)
 
1186
        {
 
1187
          my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
 
1188
          goto err;
 
1189
        }
 
1190
      }
 
1191
    }
 
1192
 
 
1193
    if (forminfo[46] == (uchar)255)
 
1194
    {
 
1195
      //reading long table comment
 
1196
      if (next_chunk + 2 > buff_end)
 
1197
      {
 
1198
          DBUG_PRINT("error",
 
1199
                     ("long table comment is not defined in .frm"));
 
1200
          goto err;
 
1201
      }
 
1202
      share->comment.length = uint2korr(next_chunk);
 
1203
      if (! (share->comment.str= strmake_root(&share->mem_root,
 
1204
             (char*)next_chunk + 2, share->comment.length)))
 
1205
      {
 
1206
          goto err;
 
1207
      }
 
1208
      next_chunk+= 2 + share->comment.length;
 
1209
    }
 
1210
 
 
1211
    DBUG_ASSERT(next_chunk <= buff_end);
 
1212
 
 
1213
    if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
 
1214
    {
 
1215
      /*
 
1216
        store options position, but skip till the time we will
 
1217
        know number of fields
 
1218
      */
 
1219
      options_len= uint4korr(next_chunk);
 
1220
      options= next_chunk + 4;
 
1221
      next_chunk+= options_len + 4;
 
1222
    }
 
1223
    DBUG_ASSERT(next_chunk <= buff_end);
 
1224
  }
 
1225
  share->key_block_size= uint2korr(head+62);
 
1226
 
 
1227
  error=4;
 
1228
  extra_rec_buf_length= uint2korr(head+59);
 
1229
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
 
1230
  share->rec_buff_length= rec_buff_length;
 
1231
  if (!(record= (uchar *) alloc_root(&share->mem_root,
 
1232
                                     rec_buff_length)))
 
1233
    goto err;                          /* purecov: inspected */
 
1234
  share->default_values= record;
 
1235
  if (mysql_file_pread(file, record, (size_t) share->reclength,
 
1236
                       record_offset, MYF(MY_NABP)))
 
1237
    goto err;                          /* purecov: inspected */
 
1238
 
 
1239
  mysql_file_seek(file, pos+288, MY_SEEK_SET, MYF(0));
 
1240
#ifdef HAVE_CRYPTED_FRM
 
1241
  if (crypted)
 
1242
  {
 
1243
    crypted->decode((char*) forminfo+256,288-256);
 
1244
    if (sint2korr(forminfo+284) != 0)           // Should be 0
 
1245
      goto err;                        // Wrong password
 
1246
  }
 
1247
#endif
 
1248
 
 
1249
  share->fields= uint2korr(forminfo+258);
 
1250
  pos= uint2korr(forminfo+260);   /* Length of all screens */
 
1251
  n_length= uint2korr(forminfo+268);
 
1252
  interval_count= uint2korr(forminfo+270);
 
1253
  interval_parts= uint2korr(forminfo+272);
 
1254
  int_length= uint2korr(forminfo+274);
 
1255
  share->null_fields= uint2korr(forminfo+282);
 
1256
  com_length= uint2korr(forminfo+284);
 
1257
  vcol_screen_length= uint2korr(forminfo+286);
 
1258
  share->vfields= 0;
 
1259
  share->stored_fields= share->fields;
 
1260
  if (forminfo[46] != (uchar)255)
 
1261
  {
 
1262
    share->comment.length=  (int) (forminfo[46]);
 
1263
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
 
1264
                                     share->comment.length);
 
1265
  }
 
1266
 
 
1267
  DBUG_PRINT("info",("i_count: %d  i_parts: %d  index: %d  n_length: %d  int_length: %d  com_length: %d  vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length));
 
1268
 
 
1269
 
 
1270
  if (!(field_ptr = (Field **)
 
1271
        alloc_root(&share->mem_root,
 
1272
                   (uint) ((share->fields+1)*sizeof(Field*)+
 
1273
                           interval_count*sizeof(TYPELIB)+
 
1274
                           (share->fields+interval_parts+
 
1275
                            keys+3)*sizeof(char *)+
 
1276
                           (n_length+int_length+com_length+
 
1277
                               vcol_screen_length)))))
 
1278
    goto err;                           /* purecov: inspected */
 
1279
 
 
1280
  share->field= field_ptr;
 
1281
  read_length=(uint) (share->fields * field_pack_length +
 
1282
                      pos+ (uint) (n_length+int_length+com_length+
 
1283
                                   vcol_screen_length));
 
1284
  if (read_string(file,(uchar**) &disk_buff,read_length))
 
1285
    goto err;                           /* purecov: inspected */
 
1286
#ifdef HAVE_CRYPTED_FRM
 
1287
  if (crypted)
 
1288
  {
 
1289
    crypted->decode((char*) disk_buff,read_length);
 
1290
    delete crypted;
 
1291
    crypted=0;
 
1292
  }
 
1293
#endif
 
1294
  strpos= disk_buff+pos;
 
1295
 
 
1296
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
 
1297
  interval_array= (const char **) (share->intervals+interval_count);
 
1298
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
 
1299
  if (!interval_count)
 
1300
    share->intervals= 0;                        // For better debugging
 
1301
  memcpy((char*) names, strpos+(share->fields*field_pack_length),
 
1302
         (uint) (n_length+int_length));
 
1303
  comment_pos= names+(n_length+int_length);
 
1304
  memcpy(comment_pos, disk_buff+read_length-com_length-vcol_screen_length, 
 
1305
         com_length);
 
1306
  vcol_screen_pos= names+(n_length+int_length+com_length);
 
1307
  memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length, 
 
1308
         vcol_screen_length);
 
1309
 
 
1310
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
 
1311
  if (share->fieldnames.count != share->fields)
 
1312
    goto err;
 
1313
  fix_type_pointers(&interval_array, share->intervals, interval_count,
 
1314
                    &names);
 
1315
 
 
1316
  {
 
1317
    /* Set ENUM and SET lengths */
 
1318
    TYPELIB *interval;
 
1319
    for (interval= share->intervals;
 
1320
         interval < share->intervals + interval_count;
 
1321
         interval++)
 
1322
    {
 
1323
      uint count= (uint) (interval->count + 1) * sizeof(uint);
 
1324
      if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
 
1325
                                                        count)))
 
1326
        goto err;
 
1327
      for (count= 0; count < interval->count; count++)
 
1328
      {
 
1329
        char *val= (char*) interval->type_names[count];
 
1330
        interval->type_lengths[count]= strlen(val);
 
1331
      }
 
1332
      interval->type_lengths[count]= 0;
 
1333
    }
 
1334
  }
 
1335
 
 
1336
  if (keynames)
 
1337
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
 
1338
 
 
1339
 /* Allocate handler */
 
1340
  if (!(handler_file= get_new_handler(share, thd->mem_root,
 
1341
                                      share->db_type())))
 
1342
    goto err;
 
1343
 
 
1344
  record= share->default_values-1;              /* Fieldstart = 1 */
 
1345
  null_bits_are_used= share->null_fields != 0;
 
1346
  if (share->null_field_first)
 
1347
  {
 
1348
    null_flags= null_pos= (uchar*) record+1;
 
1349
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
 
1350
    /*
 
1351
      null_bytes below is only correct under the condition that
 
1352
      there are no bit fields.  Correct values is set below after the
 
1353
      table struct is initialized
 
1354
    */
 
1355
    share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
 
1356
  }
 
1357
#ifndef WE_WANT_TO_SUPPORT_VERY_OLD_FRM_FILES
 
1358
  else
 
1359
  {
 
1360
    share->null_bytes= (share->null_fields+7)/8;
 
1361
    null_flags= null_pos= (uchar*) (record + 1 +share->reclength -
 
1362
                                    share->null_bytes);
 
1363
    null_bit_pos= 0;
 
1364
  }
 
1365
#endif
 
1366
 
 
1367
  use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
1368
  if (use_hash)
 
1369
    use_hash= !my_hash_init(&share->name_hash,
 
1370
                            system_charset_info,
 
1371
                            share->fields,0,0,
 
1372
                            (my_hash_get_key) get_field_name,0,0);
 
1373
 
 
1374
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
 
1375
  {
 
1376
    uint pack_flag, interval_nr, unireg_type, recpos, field_length;
 
1377
    uint vcol_info_length=0;
 
1378
    uint vcol_expr_length=0;
 
1379
    enum_field_types field_type;
 
1380
    CHARSET_INFO *charset=NULL;
 
1381
    Field::geometry_type geom_type= Field::GEOM_GEOMETRY;
 
1382
    LEX_STRING comment;
 
1383
    Virtual_column_info *vcol_info= 0;
 
1384
    bool fld_stored_in_db= TRUE;
 
1385
 
 
1386
    if (new_frm_ver >= 3)
 
1387
    {
 
1388
      /* new frm file in 4.1 */
 
1389
      field_length= uint2korr(strpos+3);
 
1390
      recpos=       uint3korr(strpos+5);
 
1391
      pack_flag=    uint2korr(strpos+8);
 
1392
      unireg_type=  (uint) strpos[10];
 
1393
      interval_nr=  (uint) strpos[12];
 
1394
      uint comment_length=uint2korr(strpos+15);
 
1395
      field_type=(enum_field_types) (uint) strpos[13];
 
1396
 
 
1397
      /* charset and geometry_type share the same byte in frm */
 
1398
      if (field_type == MYSQL_TYPE_GEOMETRY)
 
1399
      {
 
1400
#ifdef HAVE_SPATIAL
 
1401
        geom_type= (Field::geometry_type) strpos[14];
 
1402
        charset= &my_charset_bin;
 
1403
#else
 
1404
        error= 4;  // unsupported field type
 
1405
        goto err;
 
1406
#endif
 
1407
      }
 
1408
      else
 
1409
      {
 
1410
        uint csid= strpos[14] + (((uint) strpos[11]) << 8);
 
1411
        if (!csid)
 
1412
          charset= &my_charset_bin;
 
1413
        else if (!(charset= get_charset(csid, MYF(0))))
 
1414
        {
 
1415
          error= 5; // Unknown or unavailable charset
 
1416
          errarg= (int) csid;
 
1417
          goto err;
 
1418
        }
 
1419
      }
 
1420
 
 
1421
      if ((uchar)field_type == (uchar)MYSQL_TYPE_VIRTUAL)
 
1422
      {
 
1423
        DBUG_ASSERT(interval_nr); // Expect non-null expression
 
1424
        /* 
 
1425
          The interval_id byte in the .frm file stores the length of the
 
1426
          expression statement for a virtual column.
 
1427
        */
 
1428
        vcol_info_length= interval_nr;
 
1429
        interval_nr= 0;
 
1430
      }
 
1431
 
 
1432
      if (!comment_length)
 
1433
      {
 
1434
        comment.str= (char*) "";
 
1435
        comment.length=0;
 
1436
      }
 
1437
      else
 
1438
      {
 
1439
        comment.str=    (char*) comment_pos;
 
1440
        comment.length= comment_length;
 
1441
        comment_pos+=   comment_length;
 
1442
      }
 
1443
 
 
1444
      if (vcol_info_length)
 
1445
      {
 
1446
        /*
 
1447
          Get virtual column data stored in the .frm file as follows:
 
1448
          byte 1      = 1 | 2
 
1449
          byte 2      = sql_type
 
1450
          byte 3      = flags (as of now, 0 - no flags, 1 - field is physically stored)
 
1451
          [byte 4]    = optional interval_id for sql_type (only if byte 1 == 2) 
 
1452
          next byte ...  = virtual column expression (text data)
 
1453
        */
 
1454
        vcol_info= new Virtual_column_info();
 
1455
        bool opt_interval_id= (uint)vcol_screen_pos[0] == 2;
 
1456
        field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
 
1457
        if (opt_interval_id)
 
1458
          interval_nr= (uint)vcol_screen_pos[3];
 
1459
        else if ((uint)vcol_screen_pos[0] != 1)
 
1460
        {
 
1461
          error= 4;
 
1462
          goto err;
 
1463
        }
 
1464
        fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
 
1465
        vcol_expr_length= vcol_info_length -
 
1466
                          (uint)(FRM_VCOL_HEADER_SIZE(opt_interval_id));
 
1467
        if (!(vcol_info->expr_str.str=
 
1468
              (char *)memdup_root(&share->mem_root,
 
1469
                                  vcol_screen_pos +
 
1470
                                  (uint) FRM_VCOL_HEADER_SIZE(opt_interval_id),
 
1471
                                  vcol_expr_length)))
 
1472
          goto err;
 
1473
        if (opt_interval_id)
 
1474
          interval_nr= (uint) vcol_screen_pos[3];
 
1475
        vcol_info->expr_str.length= vcol_expr_length;
 
1476
        vcol_screen_pos+= vcol_info_length;
 
1477
        share->vfields++;
 
1478
      }
 
1479
    }
 
1480
    else
 
1481
    {
 
1482
      field_length= (uint) strpos[3];
 
1483
      recpos=       uint2korr(strpos+4),
 
1484
      pack_flag=    uint2korr(strpos+6);
 
1485
      pack_flag&=   ~FIELDFLAG_NO_DEFAULT;     // Safety for old files
 
1486
      unireg_type=  (uint) strpos[8];
 
1487
      interval_nr=  (uint) strpos[10];
 
1488
 
 
1489
      /* old frm file */
 
1490
      field_type= (enum_field_types) f_packtype(pack_flag);
 
1491
      if (f_is_binary(pack_flag))
 
1492
      {
 
1493
        /*
 
1494
          Try to choose the best 4.1 type:
 
1495
          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
 
1496
            try to find a binary collation for character set.
 
1497
          - for other types (e.g. BLOB) just use my_charset_bin. 
 
1498
        */
 
1499
        if (!f_is_blob(pack_flag))
 
1500
        {
 
1501
          // 3.23 or 4.0 string
 
1502
          if (!(charset= get_charset_by_csname(share->table_charset->csname,
 
1503
                                               MY_CS_BINSORT, MYF(0))))
 
1504
            charset= &my_charset_bin;
 
1505
        }
 
1506
        else
 
1507
          charset= &my_charset_bin;
 
1508
      }
 
1509
      else
 
1510
        charset= share->table_charset;
 
1511
      bzero((char*) &comment, sizeof(comment));
 
1512
    }
 
1513
 
 
1514
    if (interval_nr && charset->mbminlen > 1)
 
1515
    {
 
1516
      /* Unescape UCS2 intervals from HEX notation */
 
1517
      TYPELIB *interval= share->intervals + interval_nr - 1;
 
1518
      unhex_type2(interval);
 
1519
    }
 
1520
    
 
1521
#ifndef TO_BE_DELETED_ON_PRODUCTION
 
1522
    if (field_type == MYSQL_TYPE_NEWDECIMAL && !share->mysql_version)
 
1523
    {
 
1524
      /*
 
1525
        Fix pack length of old decimal values from 5.0.3 -> 5.0.4
 
1526
        The difference is that in the old version we stored precision
 
1527
        in the .frm table while we now store the display_length
 
1528
      */
 
1529
      uint decimals= f_decimals(pack_flag);
 
1530
      field_length= my_decimal_precision_to_length(field_length,
 
1531
                                                   decimals,
 
1532
                                                   f_is_dec(pack_flag) == 0);
 
1533
      sql_print_error("Found incompatible DECIMAL field '%s' in %s; "
 
1534
                      "Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
 
1535
                      share->fieldnames.type_names[i], share->table_name.str,
 
1536
                      share->table_name.str);
 
1537
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1538
                          ER_CRASHED_ON_USAGE,
 
1539
                          "Found incompatible DECIMAL field '%s' in %s; "
 
1540
                          "Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
 
1541
                          share->fieldnames.type_names[i],
 
1542
                          share->table_name.str,
 
1543
                          share->table_name.str);
 
1544
      share->crashed= 1;                        // Marker for CHECK TABLE
 
1545
    }
 
1546
#endif
 
1547
 
 
1548
    *field_ptr= reg_field=
 
1549
      make_field(share, record+recpos,
 
1550
                 (uint32) field_length,
 
1551
                 null_pos, null_bit_pos,
 
1552
                 pack_flag,
 
1553
                 field_type,
 
1554
                 charset,
 
1555
                 geom_type,
 
1556
                 (Field::utype) MTYP_TYPENR(unireg_type),
 
1557
                 (interval_nr ?
 
1558
                  share->intervals+interval_nr-1 :
 
1559
                  (TYPELIB*) 0),
 
1560
                 share->fieldnames.type_names[i]);
 
1561
    if (!reg_field)                             // Not supported field type
 
1562
    {
 
1563
      error= 4;
 
1564
      goto err;                 /* purecov: inspected */
 
1565
    }
 
1566
 
 
1567
    reg_field->field_index= i;
 
1568
    reg_field->comment=comment;
 
1569
    reg_field->vcol_info= vcol_info;
 
1570
    reg_field->stored_in_db= fld_stored_in_db;
 
1571
    if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag))
 
1572
    {
 
1573
      null_bits_are_used= 1;
 
1574
      if ((null_bit_pos+= field_length & 7) > 7)
 
1575
      {
 
1576
        null_pos++;
 
1577
        null_bit_pos-= 8;
 
1578
      }
 
1579
    }
 
1580
    if (!(reg_field->flags & NOT_NULL_FLAG))
 
1581
    {
 
1582
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
1583
        null_pos++;
 
1584
    }
 
1585
    if (f_no_default(pack_flag))
 
1586
      reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
 
1587
 
 
1588
    if (reg_field->unireg_check == Field::NEXT_NUMBER)
 
1589
      share->found_next_number_field= field_ptr;
 
1590
    if (share->timestamp_field == reg_field)
 
1591
      share->timestamp_field_offset= i;
 
1592
 
 
1593
    if (use_hash)
 
1594
    {
 
1595
      if (my_hash_insert(&share->name_hash,
 
1596
                         (uchar*) field_ptr))
 
1597
      {
 
1598
        /*
 
1599
          Set return code 8 here to indicate that an error has
 
1600
          occurred but that the error message already has been
 
1601
          sent (OOM).
 
1602
        */
 
1603
        error= 8; 
 
1604
        goto err;
 
1605
      }
 
1606
    }
 
1607
    if (!reg_field->stored_in_db)
 
1608
    {
 
1609
      share->stored_fields--;
 
1610
      if (share->stored_rec_length>=recpos)
 
1611
        share->stored_rec_length= recpos-1;
 
1612
    }
 
1613
  }
 
1614
  *field_ptr=0;                                 // End marker
 
1615
  /* Sanity checks: */
 
1616
  DBUG_ASSERT(share->fields>=share->stored_fields);
 
1617
  DBUG_ASSERT(share->reclength>=share->stored_rec_length);
 
1618
 
 
1619
  /* Fix key->name and key_part->field */
 
1620
  if (key_parts)
 
1621
  {
 
1622
    uint add_first_key_parts= 0;
 
1623
    uint primary_key=(uint) (find_type(primary_key_name, &share->keynames,
 
1624
                                       FIND_TYPE_NO_PREFIX) - 1);
 
1625
    longlong ha_option= handler_file->ha_table_flags();
 
1626
    keyinfo= share->key_info;
 
1627
 
 
1628
    if (share->use_ext_keys)
 
1629
    { 
 
1630
      if (primary_key >= MAX_KEY)
 
1631
      {
 
1632
        add_first_key_parts= 0;
 
1633
        share->set_use_ext_keys_flag(FALSE);
 
1634
      }
 
1635
      else
 
1636
      {
 
1637
        add_first_key_parts= first_key_parts;
 
1638
        /* 
 
1639
          Do not add components of the primary key starting from
 
1640
          the major component defined over the beginning of a field.
 
1641
        */
 
1642
        for (i= 0; i < first_key_parts; i++)
 
1643
        {
 
1644
          uint fieldnr= keyinfo[0].key_part[i].fieldnr;
 
1645
          if (share->field[fieldnr-1]->key_length() !=
 
1646
              keyinfo[0].key_part[i].length)
 
1647
          {
 
1648
            add_first_key_parts= i;
 
1649
            break;
 
1650
          }
 
1651
        }
 
1652
      }   
 
1653
    }
 
1654
 
 
1655
    for (uint key=0 ; key < share->keys ; key++,keyinfo++)
 
1656
    {
 
1657
      uint usable_parts= 0;
 
1658
      keyinfo->name=(char*) share->keynames.type_names[key];
 
1659
      keyinfo->name_length= strlen(keyinfo->name);
 
1660
      keyinfo->cache_name=
 
1661
        (uchar*) alloc_root(&share->mem_root,
 
1662
                            share->table_cache_key.length+
 
1663
                            keyinfo->name_length + 1);
 
1664
      if (keyinfo->cache_name)           // If not out of memory
 
1665
      {
 
1666
        uchar *pos= keyinfo->cache_name;
 
1667
        memcpy(pos, share->table_cache_key.str, share->table_cache_key.length);
 
1668
        memcpy(pos + share->table_cache_key.length, keyinfo->name,
 
1669
               keyinfo->name_length+1);
 
1670
      }
 
1671
 
 
1672
      if (ext_key_parts > share->key_parts && key)
 
1673
      {
 
1674
        KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part +
 
1675
                                     (keyinfo-1)->ext_key_parts;
 
1676
 
 
1677
        /* 
 
1678
          Do not extend the key that contains a component
 
1679
          defined over the beginning of a field.
 
1680
        */ 
 
1681
        for (i= 0; i < keyinfo->key_parts; i++)
 
1682
        {
 
1683
          uint fieldnr= keyinfo->key_part[i].fieldnr;
 
1684
          if (share->field[fieldnr-1]->key_length() !=
 
1685
              keyinfo->key_part[i].length)
 
1686
          {
 
1687
            add_first_key_parts= 0;
 
1688
            break;
 
1689
          }
 
1690
        }
 
1691
 
 
1692
        if (add_first_key_parts < keyinfo->ext_key_parts-keyinfo->key_parts)
 
1693
        {
 
1694
          share->ext_key_parts-= keyinfo->ext_key_parts;
 
1695
          key_part_map ext_key_part_map= keyinfo->ext_key_part_map;
 
1696
          keyinfo->ext_key_parts= keyinfo->key_parts;
 
1697
          keyinfo->ext_key_flags= keyinfo->flags;
 
1698
          keyinfo->ext_key_part_map= 0; 
 
1699
          for (i= 0; i < add_first_key_parts; i++)
 
1700
          {
 
1701
            if (ext_key_part_map & 1<<i)
 
1702
            {
 
1703
              keyinfo->ext_key_part_map|= 1<<i;
 
1704
              keyinfo->ext_key_parts++;
 
1705
            }
 
1706
          }
 
1707
          share->ext_key_parts+= keyinfo->ext_key_parts;
 
1708
        }
 
1709
        if (new_key_part != keyinfo->key_part)
 
1710
        {
 
1711
          memmove(new_key_part, keyinfo->key_part,
 
1712
                  sizeof(KEY_PART_INFO) * keyinfo->ext_key_parts);
 
1713
          keyinfo->key_part= new_key_part;
 
1714
        }
 
1715
      }
 
1716
    
 
1717
      /* Fix fulltext keys for old .frm files */
 
1718
      if (share->key_info[key].flags & HA_FULLTEXT)
 
1719
        share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
 
1720
 
 
1721
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
 
1722
      {
 
1723
        /*
 
1724
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
1725
          declare this as a primary key.
 
1726
        */
 
1727
        primary_key=key;
 
1728
        key_part= keyinfo->key_part;
 
1729
        for (i=0 ; i < keyinfo->key_parts ;i++)
 
1730
        {
 
1731
          uint fieldnr= key_part[i].fieldnr;
 
1732
          if (!fieldnr ||
 
1733
              share->field[fieldnr-1]->null_ptr ||
 
1734
              share->field[fieldnr-1]->key_length() !=
 
1735
              key_part[i].length)
 
1736
          {
 
1737
            primary_key=MAX_KEY;                // Can't be used
 
1738
            break;
 
1739
          }
 
1740
        }
 
1741
      }
 
1742
 
 
1743
      key_part= keyinfo->key_part;
 
1744
      uint key_parts= share->use_ext_keys ? keyinfo->ext_key_parts :
 
1745
                                            keyinfo->key_parts;
 
1746
      for (i=0; i < key_parts; key_part++, i++)
 
1747
      {
 
1748
        Field *field;
 
1749
        if (new_field_pack_flag <= 1)
 
1750
          key_part->fieldnr= (uint16) find_field(share->field,
 
1751
                                                 share->default_values,
 
1752
                                                 (uint) key_part->offset,
 
1753
                                                 (uint) key_part->length);
 
1754
        if (!key_part->fieldnr)
 
1755
        {
 
1756
          error= 4;                             // Wrong file
 
1757
          goto err;
 
1758
        }
 
1759
        field= key_part->field= share->field[key_part->fieldnr-1];
 
1760
        key_part->type= field->key_type();
 
1761
        if (field->null_ptr)
 
1762
        {
 
1763
          key_part->null_offset=(uint) ((uchar*) field->null_ptr -
 
1764
                                        share->default_values);
 
1765
          key_part->null_bit= field->null_bit;
 
1766
          key_part->store_length+=HA_KEY_NULL_LENGTH;
 
1767
          keyinfo->flags|=HA_NULL_PART_KEY;
 
1768
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
 
1769
        }
 
1770
        if (field->type() == MYSQL_TYPE_BLOB ||
 
1771
            field->real_type() == MYSQL_TYPE_VARCHAR ||
 
1772
            field->type() == MYSQL_TYPE_GEOMETRY)
 
1773
        {
 
1774
          if (field->type() == MYSQL_TYPE_BLOB ||
 
1775
              field->type() == MYSQL_TYPE_GEOMETRY)
 
1776
            key_part->key_part_flag|= HA_BLOB_PART;
 
1777
          else
 
1778
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
 
1779
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
 
1780
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
 
1781
        }
 
1782
        if (field->type() == MYSQL_TYPE_BIT)
 
1783
          key_part->key_part_flag|= HA_BIT_PART;
 
1784
 
 
1785
        if (i == 0 && key != primary_key)
 
1786
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
 
1787
                           (keyinfo->key_parts == 1)) ?
 
1788
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
 
1789
        if (i == 0)
 
1790
          field->key_start.set_bit(key);
 
1791
        if (field->key_length() == key_part->length &&
 
1792
            !(field->flags & BLOB_FLAG))
 
1793
        {
 
1794
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
 
1795
          {
 
1796
            share->keys_for_keyread.set_bit(key);
 
1797
            field->part_of_key.set_bit(key);
 
1798
            if (i < keyinfo->key_parts)
 
1799
              field->part_of_key_not_clustered.set_bit(key);
 
1800
          }
 
1801
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1802
            field->part_of_sortkey.set_bit(key);
 
1803
        }
 
1804
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
 
1805
            usable_parts == i)
 
1806
          usable_parts++;                       // For FILESORT
 
1807
        field->flags|= PART_KEY_FLAG;
 
1808
        if (key == primary_key)
 
1809
        {
 
1810
          field->flags|= PRI_KEY_FLAG;
 
1811
          /*
 
1812
            If this field is part of the primary key and all keys contains
 
1813
            the primary key, then we can use any key to find this column
 
1814
          */
 
1815
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
 
1816
          {
 
1817
            if (field->key_length() == key_part->length &&
 
1818
                !(field->flags & BLOB_FLAG))
 
1819
              field->part_of_key= share->keys_in_use;
 
1820
            if (field->part_of_sortkey.is_set(key))
 
1821
              field->part_of_sortkey= share->keys_in_use;
 
1822
          }
 
1823
        }
 
1824
        if (field->key_length() != key_part->length)
 
1825
        {
 
1826
#ifndef TO_BE_DELETED_ON_PRODUCTION
 
1827
          if (field->type() == MYSQL_TYPE_NEWDECIMAL)
 
1828
          {
 
1829
            /*
 
1830
              Fix a fatal error in decimal key handling that causes crashes
 
1831
              on Innodb. We fix it by reducing the key length so that
 
1832
              InnoDB never gets a too big key when searching.
 
1833
              This allows the end user to do an ALTER TABLE to fix the
 
1834
              error.
 
1835
            */
 
1836
            keyinfo->key_length-= (key_part->length - field->key_length());
 
1837
            key_part->store_length-= (uint16)(key_part->length -
 
1838
                                              field->key_length());
 
1839
            key_part->length= (uint16)field->key_length();
 
1840
            sql_print_error("Found wrong key definition in %s; "
 
1841
                            "Please do \"ALTER TABLE '%s' FORCE \" to fix it!",
 
1842
                            share->table_name.str,
 
1843
                            share->table_name.str);
 
1844
            push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1845
                                ER_CRASHED_ON_USAGE,
 
1846
                                "Found wrong key definition in %s; "
 
1847
                                "Please do \"ALTER TABLE '%s' FORCE\" to fix "
 
1848
                                "it!",
 
1849
                                share->table_name.str,
 
1850
                                share->table_name.str);
 
1851
            share->crashed= 1;                // Marker for CHECK TABLE
 
1852
            continue;
 
1853
          }
 
1854
#endif
 
1855
          key_part->key_part_flag|= HA_PART_KEY_SEG;
 
1856
        }
 
1857
        if (field->real_maybe_null())
 
1858
          key_part->key_part_flag|= HA_NULL_PART;
 
1859
        /*
 
1860
          Sometimes we can compare key parts for equality with memcmp.
 
1861
          But not always.
 
1862
        */
 
1863
        if (!(key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART |
 
1864
                                         HA_BIT_PART)) &&
 
1865
            key_part->type != HA_KEYTYPE_FLOAT &&
 
1866
            key_part->type == HA_KEYTYPE_DOUBLE)
 
1867
          key_part->key_part_flag|= HA_CAN_MEMCMP;
 
1868
      }
 
1869
      keyinfo->usable_key_parts= usable_parts; // Filesort
 
1870
 
 
1871
      set_if_bigger(share->max_key_length,keyinfo->key_length+
 
1872
                    keyinfo->key_parts);
 
1873
      share->total_key_length+= keyinfo->key_length;
 
1874
      /*
 
1875
        MERGE tables do not have unique indexes. But every key could be
 
1876
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1877
      */
 
1878
      if ((keyinfo->flags & HA_NOSAME) ||
 
1879
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
 
1880
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
 
1881
    }
 
1882
    if (primary_key < MAX_KEY &&
 
1883
        (share->keys_in_use.is_set(primary_key)))
 
1884
    {
 
1885
      share->primary_key= primary_key;
 
1886
      /*
 
1887
        If we are using an integer as the primary key then allow the user to
 
1888
        refer to it as '_rowid'
 
1889
      */
 
1890
      if (share->key_info[primary_key].key_parts == 1)
 
1891
      {
 
1892
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1893
        if (field && field->result_type() == INT_RESULT)
 
1894
        {
 
1895
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
 
1896
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1897
                                      fieldnr);
 
1898
        }
 
1899
      }
 
1900
    }
 
1901
    else
 
1902
      share->primary_key = MAX_KEY; // we do not have a primary key
 
1903
  }
 
1904
  else
 
1905
    share->primary_key= MAX_KEY;
 
1906
  my_free(disk_buff);
 
1907
  disk_buff=0;
 
1908
  if (new_field_pack_flag <= 1)
 
1909
  {
 
1910
    /* Old file format with default as not null */
 
1911
    uint null_length= (share->null_fields+7)/8;
 
1912
    bfill(share->default_values + (null_flags - (uchar*) record),
 
1913
          null_length, 255);
 
1914
  }
 
1915
 
 
1916
  if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
 
1917
  {
 
1918
    DBUG_ASSERT(options_len);
 
1919
    if (engine_table_options_frm_read(options, options_len, share))
 
1920
      goto err;
 
1921
  }
 
1922
  if (parse_engine_table_options(thd, handler_file->partition_ht(), share))
 
1923
    goto err;
 
1924
 
 
1925
  if (share->found_next_number_field)
 
1926
  {
 
1927
    reg_field= *share->found_next_number_field;
 
1928
    if ((int) (share->next_number_index= (uint)
 
1929
               find_ref_key(share->key_info, share->keys,
 
1930
                            share->default_values, reg_field,
 
1931
                            &share->next_number_key_offset,
 
1932
                            &share->next_number_keypart)) < 0)
 
1933
    {
 
1934
      /* Wrong field definition */
 
1935
      error= 4;
 
1936
      goto err;
 
1937
    }
 
1938
    else
 
1939
      reg_field->flags |= AUTO_INCREMENT_FLAG;
 
1940
  }
 
1941
 
 
1942
  if (share->blob_fields)
 
1943
  {
 
1944
    Field **ptr;
 
1945
    uint k, *save;
 
1946
 
 
1947
    /* Store offsets to blob fields to find them fast */
 
1948
    if (!(share->blob_field= save=
 
1949
          (uint*) alloc_root(&share->mem_root,
 
1950
                             (uint) (share->blob_fields* sizeof(uint)))))
 
1951
      goto err;
 
1952
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
 
1953
    {
 
1954
      if ((*ptr)->flags & BLOB_FLAG)
 
1955
        (*save++)= k;
 
1956
    }
 
1957
  }
 
1958
 
 
1959
  /*
 
1960
    the correct null_bytes can now be set, since bitfields have been taken
 
1961
    into account
 
1962
  */
 
1963
  share->null_bytes= (null_pos - (uchar*) null_flags +
 
1964
                      (null_bit_pos + 7) / 8);
 
1965
  share->last_null_bit_pos= null_bit_pos;
 
1966
  share->null_bytes_for_compare= null_bits_are_used ? share->null_bytes : 0;
 
1967
  share->can_cmp_whole_record= (share->blob_fields == 0 &&
 
1968
                                share->varchar_fields == 0);
 
1969
 
 
1970
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
 
1971
 
 
1972
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
 
1973
                                             share->column_bitmap_size)))
 
1974
    goto err;
 
1975
  bitmap_init(&share->all_set, bitmaps, share->fields, FALSE);
 
1976
  bitmap_set_all(&share->all_set);
 
1977
 
 
1978
  delete handler_file;
 
1979
#ifndef DBUG_OFF
 
1980
  if (use_hash)
 
1981
    (void) my_hash_check(&share->name_hash);
 
1982
#endif
 
1983
  my_free(extra_segment_buff);
 
1984
  DBUG_RETURN (0);
 
1985
 
 
1986
 err:
 
1987
  share->error= error;
 
1988
  share->open_errno= my_errno;
 
1989
  share->errarg= errarg;
 
1990
  my_free(disk_buff);
 
1991
  my_free(extra_segment_buff);
 
1992
  delete crypted;
 
1993
  delete handler_file;
 
1994
  my_hash_free(&share->name_hash);
 
1995
  if (share->ha_data_destroy)
 
1996
  {
 
1997
    share->ha_data_destroy(share->ha_data);
 
1998
    share->ha_data_destroy= NULL;
 
1999
  }
 
2000
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
2001
  if (share->ha_part_data_destroy)
 
2002
  {
 
2003
    share->ha_part_data_destroy(share->ha_part_data);
 
2004
    share->ha_data_destroy= NULL;
 
2005
  }
 
2006
#endif /* WITH_PARTITION_STORAGE_ENGINE */
 
2007
 
 
2008
  open_table_error(share, error, share->open_errno, errarg);
 
2009
  DBUG_RETURN(error);
 
2010
} /* open_binary_frm */
 
2011
 
 
2012
/*
 
2013
  @brief
 
2014
    Clear GET_FIXED_FIELDS_FLAG in all fields of a table
 
2015
 
 
2016
  @param
 
2017
    table     The table for whose fields the flags are to be cleared
 
2018
 
 
2019
  @note
 
2020
    This routine is used for error handling purposes.
 
2021
 
 
2022
  @return
 
2023
    none
 
2024
*/
 
2025
 
 
2026
static void clear_field_flag(TABLE *table)
 
2027
{
 
2028
  Field **ptr;
 
2029
  DBUG_ENTER("clear_field_flag");
 
2030
 
 
2031
  for (ptr= table->field; *ptr; ptr++)
 
2032
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
 
2033
  DBUG_VOID_RETURN;
 
2034
}
 
2035
 
 
2036
 
 
2037
/*
 
2038
  @brief 
 
2039
    Perform semantic analysis of the defining expression for a virtual column
 
2040
 
 
2041
  @param
 
2042
    thd           The thread object
 
2043
  @param
 
2044
    table         The table containing the virtual column
 
2045
  @param
 
2046
    vcol_field    The virtual field whose defining expression is to be analyzed
 
2047
 
 
2048
  @details
 
2049
    The function performs semantic analysis of the defining expression for
 
2050
    the virtual column vcol_field. The expression is used to compute the
 
2051
    values of this column.
 
2052
 
 
2053
  @note
 
2054
   The function exploits the fact  that the fix_fields method sets the flag 
 
2055
   GET_FIXED_FIELDS_FLAG for all fields in the item tree.
 
2056
   This flag must always be unset before returning from this function
 
2057
   since it is used for other purposes as well.
 
2058
 
 
2059
  @retval
 
2060
    TRUE           An error occurred, something was wrong with the function
 
2061
  @retval
 
2062
    FALSE          Otherwise
 
2063
*/
 
2064
 
 
2065
bool fix_vcol_expr(THD *thd,
 
2066
                   TABLE *table,
 
2067
                   Field *vcol_field)
 
2068
{
 
2069
  Virtual_column_info *vcol_info= vcol_field->vcol_info;
 
2070
  Item* func_expr= vcol_info->expr_item;
 
2071
  bool result= TRUE;
 
2072
  TABLE_LIST tables;
 
2073
  int error;
 
2074
  const char *save_where;
 
2075
  Field **ptr, *field;
 
2076
  enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
 
2077
  DBUG_ASSERT(func_expr);
 
2078
  DBUG_ENTER("fix_vcol_expr");
 
2079
 
 
2080
  thd->mark_used_columns= MARK_COLUMNS_NONE;
 
2081
 
 
2082
  save_where= thd->where;
 
2083
  thd->where= "virtual column function";
 
2084
 
 
2085
  /* Fix fields referenced to by the virtual column function */
 
2086
  error= func_expr->fix_fields(thd, (Item**)0);
 
2087
 
 
2088
  if (unlikely(error))
 
2089
  {
 
2090
    DBUG_PRINT("info", 
 
2091
    ("Field in virtual column expression does not belong to the table"));
 
2092
    goto end;
 
2093
  }
 
2094
  thd->where= save_where;
 
2095
  if (unlikely(func_expr->result_type() == ROW_RESULT))
 
2096
  {
 
2097
     my_error(ER_ROW_EXPR_FOR_VCOL, MYF(0));
 
2098
     goto end;
 
2099
  }
 
2100
#ifdef PARANOID
 
2101
  /*
 
2102
    Walk through the Item tree checking if all items are valid
 
2103
   to be part of the virtual column
 
2104
  */
 
2105
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
 
2106
  if (error)
 
2107
  {
 
2108
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
 
2109
    goto end;
 
2110
  }
 
2111
#endif
 
2112
  if (unlikely(func_expr->const_item()))
 
2113
  {
 
2114
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
 
2115
    goto end;
 
2116
  }
 
2117
  /* Ensure that this virtual column is not based on another virtual field. */
 
2118
  ptr= table->field;
 
2119
  while ((field= *(ptr++))) 
 
2120
  {
 
2121
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
 
2122
        (field->vcol_info))
 
2123
    {
 
2124
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
 
2125
      goto end;
 
2126
    }
 
2127
  }
 
2128
  result= FALSE;
 
2129
 
 
2130
end:
 
2131
 
 
2132
  /* Clear GET_FIXED_FIELDS_FLAG for the fields of the table */
 
2133
  clear_field_flag(table);
 
2134
 
 
2135
  table->get_fields_in_item_tree= FALSE;
 
2136
  thd->mark_used_columns= save_mark_used_columns;
 
2137
  table->map= 0; //Restore old value
 
2138
 
 
2139
 DBUG_RETURN(result);
 
2140
}
 
2141
 
 
2142
/*
 
2143
  @brief
 
2144
    Unpack the definition of a virtual column from its linear representation
 
2145
 
 
2146
  @param
 
2147
    thd                  The thread object
 
2148
  @param
 
2149
    mem_root             The mem_root object where to allocated memory 
 
2150
  @param
 
2151
    table                The table containing the virtual column
 
2152
  @param
 
2153
    field                The field for the virtual
 
2154
  @param  
 
2155
    vcol_expr            The string representation of the defining expression
 
2156
  @param[out]
 
2157
    error_reported       The flag to inform the caller that no other error
 
2158
                         messages are to be generated
 
2159
 
 
2160
  @details
 
2161
    The function takes string representation 'vcol_expr' of the defining
 
2162
    expression for the virtual field 'field' of the table 'table' and
 
2163
    parses it, building an item object for it. The pointer to this item is
 
2164
    placed into in field->vcol_info.expr_item. After this the function performs
 
2165
    semantic analysis of the item by calling the the function fix_vcol_expr.
 
2166
    Since the defining expression is part of the table definition the item for
 
2167
    it is created in table->memroot within the special arena TABLE::expr_arena.
 
2168
 
 
2169
  @note
 
2170
    Before passing 'vcol_expr" to the parser the function embraces it in 
 
2171
    parenthesis and prepands it a special keyword.
 
2172
  
 
2173
   @retval
 
2174
    FALSE           If a success
 
2175
   @retval
 
2176
    TRUE            Otherwise
 
2177
*/
 
2178
bool unpack_vcol_info_from_frm(THD *thd,
 
2179
                               MEM_ROOT *mem_root,
 
2180
                               TABLE *table,
 
2181
                               Field *field,
 
2182
                               LEX_STRING *vcol_expr,
 
2183
                               bool *error_reported)
 
2184
{
 
2185
  bool rc;
 
2186
  char *vcol_expr_str;
 
2187
  int str_len;
 
2188
  CHARSET_INFO *old_character_set_client;
 
2189
  Query_arena *backup_stmt_arena_ptr;
 
2190
  Query_arena backup_arena;
 
2191
  Query_arena *vcol_arena= 0;
 
2192
  Parser_state parser_state;
 
2193
  LEX *old_lex= thd->lex;
 
2194
  LEX lex;
 
2195
  DBUG_ENTER("unpack_vcol_info_from_frm");
 
2196
  DBUG_ASSERT(vcol_expr);
 
2197
 
 
2198
  old_character_set_client= thd->variables.character_set_client;
 
2199
  backup_stmt_arena_ptr= thd->stmt_arena;
 
2200
 
 
2201
  /* 
 
2202
    Step 1: Construct the input string for the parser.
 
2203
    The string to be parsed has to be of the following format:
 
2204
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)".
 
2205
  */
 
2206
  
 
2207
  if (!(vcol_expr_str= (char*) alloc_root(mem_root,
 
2208
                                          vcol_expr->length + 
 
2209
                                            parse_vcol_keyword.length + 3)))
 
2210
  {
 
2211
    DBUG_RETURN(TRUE);
 
2212
  }
 
2213
  memcpy(vcol_expr_str,
 
2214
         (char*) parse_vcol_keyword.str,
 
2215
         parse_vcol_keyword.length);
 
2216
  str_len= parse_vcol_keyword.length;
 
2217
  memcpy(vcol_expr_str + str_len, "(", 1);
 
2218
  str_len++;
 
2219
  memcpy(vcol_expr_str + str_len, 
 
2220
         (char*) vcol_expr->str, 
 
2221
         vcol_expr->length);
 
2222
  str_len+= vcol_expr->length;
 
2223
  memcpy(vcol_expr_str + str_len, ")", 1);
 
2224
  str_len++;
 
2225
  memcpy(vcol_expr_str + str_len, "\0", 1);
 
2226
  str_len++;
 
2227
 
 
2228
  if (parser_state.init(thd, vcol_expr_str, str_len))
 
2229
    goto err;
 
2230
 
 
2231
  /* 
 
2232
    Step 2: Setup thd for parsing.
 
2233
  */
 
2234
  vcol_arena= table->expr_arena;
 
2235
  if (!vcol_arena)
 
2236
  {
 
2237
    /*
 
2238
      We need to use CONVENTIONAL_EXECUTION here to ensure that
 
2239
      any new items created by fix_fields() are not reverted.
 
2240
    */
 
2241
    Query_arena expr_arena(mem_root,
 
2242
                           Query_arena::STMT_CONVENTIONAL_EXECUTION);
 
2243
    if (!(vcol_arena= (Query_arena *) alloc_root(mem_root,
 
2244
                                               sizeof(Query_arena))))
 
2245
      goto err;
 
2246
    *vcol_arena= expr_arena;
 
2247
    table->expr_arena= vcol_arena;
 
2248
  }
 
2249
  thd->set_n_backup_active_arena(vcol_arena, &backup_arena);
 
2250
  thd->stmt_arena= vcol_arena;
 
2251
 
 
2252
  if (init_lex_with_single_table(thd, table, &lex))
 
2253
    goto err;
 
2254
 
 
2255
  thd->lex->parse_vcol_expr= TRUE;
 
2256
 
 
2257
  /* 
 
2258
    Step 3: Use the parser to build an Item object from vcol_expr_str.
 
2259
  */
 
2260
  if (parse_sql(thd, &parser_state, NULL))
 
2261
  {
 
2262
    goto err;
 
2263
  }
 
2264
  /* From now on use vcol_info generated by the parser. */
 
2265
  field->vcol_info= thd->lex->vcol_info;
 
2266
 
 
2267
  /* Validate the Item tree. */
 
2268
  if (fix_vcol_expr(thd, table, field))
 
2269
  {
 
2270
    *error_reported= TRUE;
 
2271
    field->vcol_info= 0;
 
2272
    goto err;
 
2273
  }
 
2274
  rc= FALSE;
 
2275
  goto end;
 
2276
 
 
2277
err:
 
2278
  rc= TRUE;
 
2279
  thd->free_items();
 
2280
end:
 
2281
  thd->stmt_arena= backup_stmt_arena_ptr;
 
2282
  if (vcol_arena)
 
2283
    thd->restore_active_arena(vcol_arena, &backup_arena);
 
2284
  end_lex_with_single_table(thd, table, old_lex);
 
2285
  thd->variables.character_set_client= old_character_set_client;
 
2286
 
 
2287
  DBUG_RETURN(rc);
 
2288
}
 
2289
 
 
2290
/*
 
2291
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
 
2292
*/
 
2293
 
 
2294
/*
 
2295
  Open a table based on a TABLE_SHARE
 
2296
 
 
2297
  SYNOPSIS
 
2298
    open_table_from_share()
 
2299
    thd                 Thread handler
 
2300
    share               Table definition
 
2301
    alias               Alias for table
 
2302
    db_stat             open flags (for example HA_OPEN_KEYFILE|
 
2303
                        HA_OPEN_RNDFILE..) can be 0 (example in
 
2304
                        ha_example_table)
 
2305
    prgflag             READ_ALL etc..
 
2306
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
 
2307
    outparam            result table
 
2308
 
 
2309
  RETURN VALUES
 
2310
   0    ok
 
2311
   1    Error (see open_table_error)
 
2312
   2    Error (see open_table_error)
 
2313
   3    Wrong data in .frm file
 
2314
   4    Error (see open_table_error)
 
2315
   5    Error (see open_table_error: charset unavailable)
 
2316
   7    Table definition has changed in engine
 
2317
*/
 
2318
 
 
2319
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
 
2320
                          uint db_stat, uint prgflag, uint ha_open_flags,
 
2321
                          TABLE *outparam, bool is_create_table)
 
2322
{
 
2323
  int error;
 
2324
  uint records, i, bitmap_size;
 
2325
  bool error_reported= FALSE;
 
2326
  uchar *record, *bitmaps;
 
2327
  Field **field_ptr, **vfield_ptr;
 
2328
  uint8 save_context_analysis_only= thd->lex->context_analysis_only;
 
2329
  DBUG_ENTER("open_table_from_share");
 
2330
  DBUG_PRINT("enter",("name: '%s.%s'  form: 0x%lx", share->db.str,
 
2331
                      share->table_name.str, (long) outparam));
 
2332
 
 
2333
  thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_VIEW; // not a view
 
2334
 
 
2335
  error= 1;
 
2336
  bzero((char*) outparam, sizeof(*outparam));
 
2337
  outparam->in_use= thd;
 
2338
  outparam->s= share;
 
2339
  outparam->db_stat= db_stat;
 
2340
  outparam->write_row_record= NULL;
 
2341
 
 
2342
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
2343
 
 
2344
  if (outparam->alias.copy(alias, strlen(alias), table_alias_charset))
 
2345
    goto err;
 
2346
  outparam->quick_keys.init();
 
2347
  outparam->covering_keys.init();
 
2348
  outparam->merge_keys.init();
 
2349
  outparam->keys_in_use_for_query.init();
 
2350
 
 
2351
  /* Allocate handler */
 
2352
  outparam->file= 0;
 
2353
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
2354
  {
 
2355
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
2356
                                          share->db_type())))
 
2357
      goto err;
 
2358
  }
 
2359
  else
 
2360
  {
 
2361
    DBUG_ASSERT(!db_stat);
 
2362
  }
 
2363
 
 
2364
  error= 4;
 
2365
  outparam->reginfo.lock_type= TL_UNLOCK;
 
2366
  outparam->current_lock= F_UNLCK;
 
2367
  records=0;
 
2368
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
 
2369
    records=1;
 
2370
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
2371
    records++;
 
2372
 
 
2373
  if (!(record= (uchar*) alloc_root(&outparam->mem_root,
 
2374
                                   share->rec_buff_length * records)))
 
2375
    goto err;                                   /* purecov: inspected */
 
2376
 
 
2377
  if (records == 0)
 
2378
  {
 
2379
    /* We are probably in hard repair, and the buffers should not be used */
 
2380
    outparam->record[0]= outparam->record[1]= share->default_values;
 
2381
  }
 
2382
  else
 
2383
  {
 
2384
    outparam->record[0]= record;
 
2385
    if (records > 1)
 
2386
      outparam->record[1]= record+ share->rec_buff_length;
 
2387
    else
 
2388
      outparam->record[1]= outparam->record[0];   // Safety
 
2389
  }
 
2390
 
 
2391
#ifdef HAVE_valgrind
 
2392
  /*
 
2393
    We need this because when we read var-length rows, we are not updating
 
2394
    bytes after end of varchar
 
2395
  */
 
2396
  if (records > 1)
 
2397
  {
 
2398
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
 
2399
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
 
2400
    if (records > 2)
 
2401
      memcpy(outparam->record[1], share->default_values,
 
2402
             share->rec_buff_length);
 
2403
  }
 
2404
#endif
 
2405
 
 
2406
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
 
2407
                                          (uint) ((share->fields+1)*
 
2408
                                                  sizeof(Field*)))))
 
2409
    goto err;                                   /* purecov: inspected */
 
2410
 
 
2411
  outparam->field= field_ptr;
 
2412
 
 
2413
  record= (uchar*) outparam->record[0]-1;       /* Fieldstart = 1 */
 
2414
  if (share->null_field_first)
 
2415
    outparam->null_flags= (uchar*) record+1;
 
2416
  else
 
2417
    outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
 
2418
                                    share->null_bytes);
 
2419
 
 
2420
  /* Setup copy of fields from share, but use the right alias and record */
 
2421
  for (i=0 ; i < share->fields; i++, field_ptr++)
 
2422
  {
 
2423
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
 
2424
      goto err;
 
2425
  }
 
2426
  (*field_ptr)= 0;                              // End marker
 
2427
 
 
2428
  if (share->found_next_number_field)
 
2429
    outparam->found_next_number_field=
 
2430
      outparam->field[(uint) (share->found_next_number_field - share->field)];
 
2431
  if (share->timestamp_field)
 
2432
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
 
2433
 
 
2434
 
 
2435
  /* Fix key->name and key_part->field */
 
2436
  if (share->key_parts)
 
2437
  {
 
2438
    KEY *key_info, *key_info_end;
 
2439
    KEY_PART_INFO *key_part;
 
2440
    uint n_length;
 
2441
    n_length= share->keys*sizeof(KEY) + share->ext_key_parts*sizeof(KEY_PART_INFO);
 
2442
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
 
2443
      goto err;
 
2444
    outparam->key_info= key_info;
 
2445
    key_part= (reinterpret_cast<KEY_PART_INFO*>(key_info+share->keys));
 
2446
 
 
2447
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
 
2448
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
 
2449
                                                   share->ext_key_parts));
 
2450
 
 
2451
    for (key_info_end= key_info + share->keys ;
 
2452
         key_info < key_info_end ;
 
2453
         key_info++)
 
2454
    {
 
2455
      KEY_PART_INFO *key_part_end;
 
2456
 
 
2457
      key_info->table= outparam;
 
2458
      key_info->key_part= key_part;
 
2459
 
 
2460
      key_part_end= key_part + (share->use_ext_keys ? key_info->ext_key_parts :
 
2461
                                                      key_info->key_parts) ;      
 
2462
      for ( ; key_part < key_part_end; key_part++)
 
2463
      {
 
2464
        Field *field= key_part->field= outparam->field[key_part->fieldnr - 1];
 
2465
 
 
2466
        if (field->key_length() != key_part->length &&
 
2467
            !(field->flags & BLOB_FLAG))
 
2468
        {
 
2469
          /*
 
2470
            We are using only a prefix of the column as a key:
 
2471
            Create a new field for the key part that matches the index
 
2472
          */
 
2473
          field= key_part->field=field->new_field(&outparam->mem_root,
 
2474
                                                  outparam, 0);
 
2475
          field->field_length= key_part->length;
 
2476
        }
 
2477
      }
 
2478
      if (!share->use_ext_keys)
 
2479
        key_part+= key_info->ext_key_parts - key_info->key_parts;
 
2480
    }
 
2481
  }
 
2482
 
 
2483
  /*
 
2484
    Process virtual columns, if any.
 
2485
  */
 
2486
  if (!share->vfields)
 
2487
    outparam->vfield= NULL;
 
2488
  else
 
2489
  {
 
2490
    if (!(vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
 
2491
                                             (uint) ((share->vfields+1)*
 
2492
                                                     sizeof(Field*)))))
 
2493
      goto err;
 
2494
 
 
2495
    outparam->vfield= vfield_ptr;
 
2496
 
 
2497
    for (field_ptr= outparam->field; *field_ptr; field_ptr++)
 
2498
    {
 
2499
      if ((*field_ptr)->vcol_info)
 
2500
      {
 
2501
        if (unpack_vcol_info_from_frm(thd,
 
2502
                                      &outparam->mem_root,
 
2503
                                      outparam,
 
2504
                                      *field_ptr,
 
2505
                                      &(*field_ptr)->vcol_info->expr_str,
 
2506
                                      &error_reported))
 
2507
        {
 
2508
          error= 4; // in case no error is reported
 
2509
          goto err;
 
2510
        }
 
2511
        *(vfield_ptr++)= *field_ptr;
 
2512
      }
 
2513
    }
 
2514
    *vfield_ptr= 0;                              // End marker
 
2515
  }
 
2516
 
 
2517
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
2518
  if (share->partition_info_str_len && outparam->file)
 
2519
  {
 
2520
  /*
 
2521
    In this execution we must avoid calling thd->change_item_tree since
 
2522
    we might release memory before statement is completed. We do this
 
2523
    by changing to a new statement arena. As part of this arena we also
 
2524
    set the memory root to be the memory root of the table since we
 
2525
    call the parser and fix_fields which both can allocate memory for
 
2526
    item objects. We keep the arena to ensure that we can release the
 
2527
    free_list when closing the table object.
 
2528
    SEE Bug #21658
 
2529
  */
 
2530
 
 
2531
    Query_arena *backup_stmt_arena_ptr= thd->stmt_arena;
 
2532
    Query_arena backup_arena;
 
2533
    Query_arena part_func_arena(&outparam->mem_root,
 
2534
                                Query_arena::STMT_INITIALIZED);
 
2535
    thd->set_n_backup_active_arena(&part_func_arena, &backup_arena);
 
2536
    thd->stmt_arena= &part_func_arena;
 
2537
    bool tmp;
 
2538
    bool work_part_info_used;
 
2539
 
 
2540
    tmp= mysql_unpack_partition(thd, share->partition_info_str,
 
2541
                                share->partition_info_str_len,
 
2542
                                outparam, is_create_table,
 
2543
                                share->default_part_db_type,
 
2544
                                &work_part_info_used);
 
2545
    if (tmp)
 
2546
    {
 
2547
      thd->stmt_arena= backup_stmt_arena_ptr;
 
2548
      thd->restore_active_arena(&part_func_arena, &backup_arena);
 
2549
      goto partititon_err;
 
2550
    }
 
2551
    outparam->part_info->is_auto_partitioned= share->auto_partitioned;
 
2552
    DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
 
2553
    /* we should perform the fix_partition_func in either local or
 
2554
       caller's arena depending on work_part_info_used value
 
2555
    */
 
2556
    if (!work_part_info_used)
 
2557
      tmp= fix_partition_func(thd, outparam, is_create_table);
 
2558
    thd->stmt_arena= backup_stmt_arena_ptr;
 
2559
    thd->restore_active_arena(&part_func_arena, &backup_arena);
 
2560
    if (!tmp)
 
2561
    {
 
2562
      if (work_part_info_used)
 
2563
        tmp= fix_partition_func(thd, outparam, is_create_table);
 
2564
    }
 
2565
    outparam->part_info->item_free_list= part_func_arena.free_list;
 
2566
partititon_err:
 
2567
    if (tmp)
 
2568
    {
 
2569
      if (is_create_table)
 
2570
      {
 
2571
        /*
 
2572
          During CREATE/ALTER TABLE it is ok to receive errors here.
 
2573
          It is not ok if it happens during the opening of an frm
 
2574
          file as part of a normal query.
 
2575
        */
 
2576
        error_reported= TRUE;
 
2577
      }
 
2578
      goto err;
 
2579
    }
 
2580
  }
 
2581
#endif
 
2582
 
 
2583
  /* Check virtual columns against table's storage engine. */
 
2584
  if (share->vfields && 
 
2585
        (outparam->file && 
 
2586
          !(outparam->file->ha_table_flags() & HA_CAN_VIRTUAL_COLUMNS)))
 
2587
  {
 
2588
    my_error(ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS, MYF(0),
 
2589
             plugin_name(share->db_plugin)->str);
 
2590
    error_reported= TRUE;
 
2591
    goto err;
 
2592
  }
 
2593
 
 
2594
  /* Allocate bitmaps */
 
2595
 
 
2596
  bitmap_size= share->column_bitmap_size;
 
2597
  if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*5)))
 
2598
    goto err;
 
2599
  bitmap_init(&outparam->def_read_set,
 
2600
              (my_bitmap_map*) bitmaps, share->fields, FALSE);
 
2601
  bitmap_init(&outparam->def_write_set,
 
2602
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE);
 
2603
  bitmap_init(&outparam->def_vcol_set,
 
2604
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE);
 
2605
  bitmap_init(&outparam->tmp_set,
 
2606
              (my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE);
 
2607
  bitmap_init(&outparam->eq_join_set,
 
2608
              (my_bitmap_map*) (bitmaps+bitmap_size*4), share->fields, FALSE);
 
2609
  outparam->default_column_bitmaps();
 
2610
 
 
2611
  /* The table struct is now initialized;  Open the table */
 
2612
  error= 2;
 
2613
  if (db_stat)
 
2614
  {
 
2615
    int ha_err;
 
2616
    if ((ha_err= (outparam->file->
 
2617
                  ha_open(outparam, share->normalized_path.str,
 
2618
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
 
2619
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
 
2620
                           ((db_stat & HA_WAIT_IF_LOCKED) ||
 
2621
                            (specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
 
2622
                           HA_OPEN_WAIT_IF_LOCKED :
 
2623
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
 
2624
                          HA_OPEN_ABORT_IF_LOCKED :
 
2625
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
 
2626
    {
 
2627
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
2628
      share->crashed= (outparam->file->auto_repair(ha_err) &&
 
2629
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
2630
 
 
2631
      switch (ha_err)
 
2632
      {
 
2633
        case HA_ERR_NO_SUCH_TABLE:
 
2634
          /*
 
2635
            The table did not exists in storage engine, use same error message
 
2636
            as if the .frm file didn't exist
 
2637
          */
 
2638
          error= 1;
 
2639
          my_errno= ENOENT;
 
2640
          break;
 
2641
        case EMFILE:
 
2642
          /*
 
2643
            Too many files opened, use same error message as if the .frm
 
2644
            file can't open
 
2645
           */
 
2646
          DBUG_PRINT("error", ("open file: %s failed, too many files opened (errno: %d)", 
 
2647
                  share->normalized_path.str, ha_err));
 
2648
          error= 1;
 
2649
          my_errno= EMFILE;
 
2650
          break;
 
2651
        default:
 
2652
          outparam->file->print_error(ha_err, MYF(0));
 
2653
          error_reported= TRUE;
 
2654
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
 
2655
            error= 7;
 
2656
          break;
 
2657
      }
 
2658
      goto err;                                 /* purecov: inspected */
 
2659
    }
 
2660
  }
 
2661
 
 
2662
#if defined(HAVE_valgrind) && !defined(DBUG_OFF)
 
2663
  bzero((char*) bitmaps, bitmap_size*3);
 
2664
#endif
 
2665
 
 
2666
  outparam->no_replicate= outparam->file &&
 
2667
                          test(outparam->file->ha_table_flags() &
 
2668
                               HA_HAS_OWN_BINLOGGING);
 
2669
  thd->status_var.opened_tables++;
 
2670
 
 
2671
  thd->lex->context_analysis_only= save_context_analysis_only;
 
2672
  DBUG_RETURN (0);
 
2673
 
 
2674
 err:
 
2675
  if (! error_reported)
 
2676
    open_table_error(share, error, my_errno, 0);
 
2677
  delete outparam->file;
 
2678
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
2679
  if (outparam->part_info)
 
2680
    free_items(outparam->part_info->item_free_list);
 
2681
#endif
 
2682
  outparam->file= 0;                            // For easier error checking
 
2683
  outparam->db_stat=0;
 
2684
  thd->lex->context_analysis_only= save_context_analysis_only;
 
2685
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on bzero'd root
 
2686
  outparam->alias.free();
 
2687
  DBUG_RETURN (error);
 
2688
}
 
2689
 
 
2690
 
 
2691
/*
 
2692
  Free information allocated by openfrm
 
2693
 
 
2694
  SYNOPSIS
 
2695
    closefrm()
 
2696
    table               TABLE object to free
 
2697
    free_share          Is 1 if we also want to free table_share
 
2698
*/
 
2699
 
 
2700
int closefrm(register TABLE *table, bool free_share)
 
2701
{
 
2702
  int error=0;
 
2703
  DBUG_ENTER("closefrm");
 
2704
  DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
 
2705
 
 
2706
  if (table->db_stat)
 
2707
  {
 
2708
    if (table->s->deleting)
 
2709
      table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
 
2710
    error=table->file->ha_close();
 
2711
  }
 
2712
  table->alias.free();
 
2713
  if (table->expr_arena)
 
2714
    table->expr_arena->free_items();
 
2715
  if (table->field)
 
2716
  {
 
2717
    for (Field **ptr=table->field ; *ptr ; ptr++)
 
2718
    {
 
2719
      delete *ptr;
 
2720
    }
 
2721
    table->field= 0;
 
2722
  }
 
2723
  delete table->file;
 
2724
  table->file= 0;                               /* For easier errorchecking */
 
2725
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
2726
  if (table->part_info)
 
2727
  {
 
2728
    free_items(table->part_info->item_free_list);
 
2729
    table->part_info->item_free_list= 0;
 
2730
    table->part_info= 0;
 
2731
  }
 
2732
#endif
 
2733
  if (free_share)
 
2734
  {
 
2735
    if (table->s->tmp_table == NO_TMP_TABLE)
 
2736
      release_table_share(table->s);
 
2737
    else
 
2738
      free_table_share(table->s);
 
2739
  }
 
2740
  free_root(&table->mem_root, MYF(0));
 
2741
  DBUG_RETURN(error);
 
2742
}
 
2743
 
 
2744
 
 
2745
/* Deallocate temporary blob storage */
 
2746
 
 
2747
void free_blobs(register TABLE *table)
 
2748
{
 
2749
  uint *ptr, *end;
 
2750
  for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
 
2751
       ptr != end ;
 
2752
       ptr++)
 
2753
  {
 
2754
    /*
 
2755
      Reduced TABLE objects which are used by row-based replication for
 
2756
      type conversion might have some fields missing. Skip freeing BLOB
 
2757
      buffers for such missing fields.
 
2758
    */
 
2759
    if (table->field[*ptr])
 
2760
      ((Field_blob*) table->field[*ptr])->free();
 
2761
  }
 
2762
}
 
2763
 
 
2764
 
 
2765
/**
 
2766
  Reclaim temporary blob storage which is bigger than 
 
2767
  a threshold.
 
2768
 
 
2769
  @param table A handle to the TABLE object containing blob fields
 
2770
  @param size The threshold value.
 
2771
 
 
2772
*/
 
2773
 
 
2774
void free_field_buffers_larger_than(TABLE *table, uint32 size)
 
2775
{
 
2776
  uint *ptr, *end;
 
2777
  for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
 
2778
       ptr != end ;
 
2779
       ptr++)
 
2780
  {
 
2781
    Field_blob *blob= (Field_blob*) table->field[*ptr];
 
2782
    if (blob->get_field_buffer_size() > size)
 
2783
        blob->free();
 
2784
  }
 
2785
}
 
2786
 
 
2787
/**
 
2788
  Find where a form starts.
 
2789
 
 
2790
  @param head The start of the form file.
 
2791
 
 
2792
  @remark If formname is NULL then only formnames is read.
 
2793
 
 
2794
  @retval The form position.
 
2795
*/
 
2796
 
 
2797
static ulong get_form_pos(File file, uchar *head)
 
2798
{
 
2799
  uchar *pos, *buf;
 
2800
  uint names, length;
 
2801
  ulong ret_value=0;
 
2802
  DBUG_ENTER("get_form_pos");
 
2803
 
 
2804
  names= uint2korr(head+8);
 
2805
 
 
2806
  if (!(names= uint2korr(head+8)))
 
2807
    DBUG_RETURN(0);
 
2808
 
 
2809
  length= uint2korr(head+4);
 
2810
 
 
2811
  mysql_file_seek(file, 64L, MY_SEEK_SET, MYF(0));
 
2812
 
 
2813
  if (!(buf= (uchar*) my_malloc(length+names*4, MYF(MY_WME))))
 
2814
    DBUG_RETURN(0);
 
2815
 
 
2816
  if (mysql_file_read(file, buf, length+names*4, MYF(MY_NABP)))
 
2817
  {
 
2818
    my_free(buf);
 
2819
    DBUG_RETURN(0);
 
2820
  }
 
2821
 
 
2822
  pos= buf+length;
 
2823
  ret_value= uint4korr(pos);
 
2824
 
 
2825
  my_free(buf);
 
2826
 
 
2827
  DBUG_RETURN(ret_value);
 
2828
}
 
2829
 
 
2830
 
 
2831
/*
 
2832
  Read string from a file with malloc
 
2833
 
 
2834
  NOTES:
 
2835
    We add an \0 at end of the read string to make reading of C strings easier
 
2836
*/
 
2837
 
 
2838
int read_string(File file, uchar**to, size_t length)
 
2839
{
 
2840
  DBUG_ENTER("read_string");
 
2841
 
 
2842
  my_free(*to);
 
2843
  if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
 
2844
      mysql_file_read(file, *to, length, MYF(MY_NABP)))
 
2845
  {
 
2846
     my_free(*to);                            /* purecov: inspected */
 
2847
    *to= 0;                                   /* purecov: inspected */
 
2848
    DBUG_RETURN(1);                           /* purecov: inspected */
 
2849
  }
 
2850
  *((char*) *to+length)= '\0';
 
2851
  DBUG_RETURN (0);
 
2852
} /* read_string */
 
2853
 
 
2854
 
 
2855
        /* Add a new form to a form file */
 
2856
 
 
2857
ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
 
2858
                     const char *newname)
 
2859
{
 
2860
  uint i,bufflength,maxlength,n_length,length,names;
 
2861
  ulong endpos,newpos;
 
2862
  uchar buff[IO_SIZE];
 
2863
  uchar *pos;
 
2864
  DBUG_ENTER("make_new_entry");
 
2865
 
 
2866
  length=(uint) strlen(newname)+1;
 
2867
  n_length=uint2korr(fileinfo+4);
 
2868
  maxlength=uint2korr(fileinfo+6);
 
2869
  names=uint2korr(fileinfo+8);
 
2870
  newpos=uint4korr(fileinfo+10);
 
2871
 
 
2872
  if (64+length+n_length+(names+1)*4 > maxlength)
 
2873
  {                                             /* Expand file */
 
2874
    newpos+=IO_SIZE;
 
2875
    int4store(fileinfo+10,newpos);
 
2876
    /* Copy from file-end */
 
2877
    endpos= (ulong) mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0));
 
2878
    bufflength= (uint) (endpos & (IO_SIZE-1));  /* IO_SIZE is a power of 2 */
 
2879
 
 
2880
    while (endpos > maxlength)
 
2881
    {
 
2882
      mysql_file_seek(file, (ulong) (endpos-bufflength), MY_SEEK_SET, MYF(0));
 
2883
      if (mysql_file_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
 
2884
        DBUG_RETURN(0L);
 
2885
      mysql_file_seek(file, (ulong) (endpos-bufflength+IO_SIZE), MY_SEEK_SET,
 
2886
                      MYF(0));
 
2887
      if ((mysql_file_write(file, buff, bufflength, MYF(MY_NABP+MY_WME))))
 
2888
        DBUG_RETURN(0);
 
2889
      endpos-=bufflength; bufflength=IO_SIZE;
 
2890
    }
 
2891
    bzero(buff,IO_SIZE);                        /* Null new block */
 
2892
    mysql_file_seek(file, (ulong) maxlength, MY_SEEK_SET, MYF(0));
 
2893
    if (mysql_file_write(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
 
2894
        DBUG_RETURN(0L);
 
2895
    maxlength+=IO_SIZE;                         /* Fix old ref */
 
2896
    int2store(fileinfo+6,maxlength);
 
2897
    for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
 
2898
         pos+=4)
 
2899
    {
 
2900
      endpos=uint4korr(pos)+IO_SIZE;
 
2901
      int4store(pos,endpos);
 
2902
    }
 
2903
  }
 
2904
 
 
2905
  if (n_length == 1 )
 
2906
  {                                             /* First name */
 
2907
    length++;
 
2908
    (void) strxmov((char*) buff,"/",newname,"/",NullS);
 
2909
  }
 
2910
  else
 
2911
    (void) strxmov((char*) buff,newname,"/",NullS); /* purecov: inspected */
 
2912
  mysql_file_seek(file, 63L+(ulong) n_length, MY_SEEK_SET, MYF(0));
 
2913
  if (mysql_file_write(file, buff, (size_t) length+1, MYF(MY_NABP+MY_WME)) ||
 
2914
      (names && mysql_file_write(file,
 
2915
                                 (uchar*) (*formnames->type_names+n_length-1),
 
2916
                                 names*4, MYF(MY_NABP+MY_WME))) ||
 
2917
      mysql_file_write(file, fileinfo+10, 4, MYF(MY_NABP+MY_WME)))
 
2918
    DBUG_RETURN(0L); /* purecov: inspected */
 
2919
 
 
2920
  int2store(fileinfo+8,names+1);
 
2921
  int2store(fileinfo+4,n_length+length);
 
2922
  (void) mysql_file_chsize(file, newpos, 0, MYF(MY_WME));/* Append file with '\0' */
 
2923
  DBUG_RETURN(newpos);
 
2924
} /* make_new_entry */
 
2925
 
 
2926
 
 
2927
        /* error message when opening a form file */
 
2928
 
 
2929
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
 
2930
{
 
2931
  int err_no;
 
2932
  char buff[FN_REFLEN];
 
2933
  myf errortype= ME_ERROR+ME_WAITTANG;          // Write fatals error to log
 
2934
  DBUG_ENTER("open_table_error");
 
2935
 
 
2936
  switch (error) {
 
2937
  case 7:
 
2938
  case 1:
 
2939
    /*
 
2940
      Test if file didn't exists. We have to also test for EINVAL as this
 
2941
      may happen on windows when opening a file with a not legal file name
 
2942
    */
 
2943
    if (db_errno == ENOENT || db_errno == EINVAL)
 
2944
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
 
2945
    else
 
2946
    {
 
2947
      strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
2948
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
 
2949
               errortype, buff, db_errno);
 
2950
    }
 
2951
    break;
 
2952
  case 2:
 
2953
  {
 
2954
    handler *file= 0;
 
2955
    const char *datext= "";
 
2956
    
 
2957
    if (share->db_type() != NULL)
 
2958
    {
 
2959
      if ((file= get_new_handler(share, current_thd->mem_root,
 
2960
                                 share->db_type())))
 
2961
      {
 
2962
        if (!(datext= *file->bas_ext()))
 
2963
          datext= "";
 
2964
      }
 
2965
    }
 
2966
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
 
2967
      ER_FILE_USED : ER_CANT_OPEN_FILE;
 
2968
    strxmov(buff, share->normalized_path.str, datext, NullS);
 
2969
    my_error(err_no,errortype, buff, db_errno);
 
2970
    delete file;
 
2971
    break;
 
2972
  }
 
2973
  case 5:
 
2974
  {
 
2975
    const char *csname= get_charset_name((uint) errarg);
 
2976
    char tmp[10];
 
2977
    if (!csname || csname[0] =='?')
 
2978
    {
 
2979
      my_snprintf(tmp, sizeof(tmp), "#%d", errarg);
 
2980
      csname= tmp;
 
2981
    }
 
2982
    my_printf_error(ER_UNKNOWN_COLLATION,
 
2983
                    "Unknown collation '%s' in table '%-.64s' definition", 
 
2984
                    MYF(0), csname, share->table_name.str);
 
2985
    break;
 
2986
  }
 
2987
  case 6:
 
2988
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
2989
    my_printf_error(ER_NOT_FORM_FILE,
 
2990
                    "Table '%-.64s' was created with a different version "
 
2991
                    "of MySQL and cannot be read", 
 
2992
                    MYF(0), buff);
 
2993
    break;
 
2994
  case 8:
 
2995
    break;
 
2996
  default:                              /* Better wrong error than none */
 
2997
  case 4:
 
2998
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
2999
    my_error(ER_NOT_FORM_FILE, errortype, buff);
 
3000
    break;
 
3001
  }
 
3002
  DBUG_VOID_RETURN;
 
3003
} /* open_table_error */
 
3004
 
 
3005
 
 
3006
        /*
 
3007
        ** fix a str_type to a array type
 
3008
        ** typeparts separated with some char. differents types are separated
 
3009
        ** with a '\0'
 
3010
        */
 
3011
 
 
3012
static void
 
3013
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
 
3014
                  char **names)
 
3015
{
 
3016
  char *type_name, *ptr;
 
3017
  char chr;
 
3018
 
 
3019
  ptr= *names;
 
3020
  while (types--)
 
3021
  {
 
3022
    point_to_type->name=0;
 
3023
    point_to_type->type_names= *array;
 
3024
 
 
3025
    if ((chr= *ptr))                    /* Test if empty type */
 
3026
    {
 
3027
      while ((type_name=strchr(ptr+1,chr)) != NullS)
 
3028
      {
 
3029
        *((*array)++) = ptr+1;
 
3030
        *type_name= '\0';               /* End string */
 
3031
        ptr=type_name;
 
3032
      }
 
3033
      ptr+=2;                           /* Skip end mark and last 0 */
 
3034
    }
 
3035
    else
 
3036
      ptr++;
 
3037
    point_to_type->count= (uint) (*array - point_to_type->type_names);
 
3038
    point_to_type++;
 
3039
    *((*array)++)= NullS;               /* End of type */
 
3040
  }
 
3041
  *names=ptr;                           /* Update end */
 
3042
  return;
 
3043
} /* fix_type_pointers */
 
3044
 
 
3045
 
 
3046
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
 
3047
{
 
3048
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
 
3049
  if (!result)
 
3050
    return 0;
 
3051
  result->count=strings.elements;
 
3052
  result->name="";
 
3053
  uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
3054
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
 
3055
    return 0;
 
3056
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
 
3057
  List_iterator<String> it(strings);
 
3058
  String *tmp;
 
3059
  for (uint i=0; (tmp=it++) ; i++)
 
3060
  {
 
3061
    result->type_names[i]= tmp->ptr();
 
3062
    result->type_lengths[i]= tmp->length();
 
3063
  }
 
3064
  result->type_names[result->count]= 0;         // End marker
 
3065
  result->type_lengths[result->count]= 0;
 
3066
  return result;
 
3067
}
 
3068
 
 
3069
 
 
3070
/*
 
3071
 Search after a field with given start & length
 
3072
 If an exact field isn't found, return longest field with starts
 
3073
 at right position.
 
3074
 
 
3075
 NOTES
 
3076
   This is needed because in some .frm fields 'fieldnr' was saved wrong
 
3077
 
 
3078
 RETURN
 
3079
   0  error
 
3080
   #  field number +1
 
3081
*/
 
3082
 
 
3083
static uint find_field(Field **fields, uchar *record, uint start, uint length)
 
3084
{
 
3085
  Field **field;
 
3086
  uint i, pos;
 
3087
 
 
3088
  pos= 0;
 
3089
  for (field= fields, i=1 ; *field ; i++,field++)
 
3090
  {
 
3091
    if ((*field)->offset(record) == start)
 
3092
    {
 
3093
      if ((*field)->key_length() == length)
 
3094
        return (i);
 
3095
      if (!pos || fields[pos-1]->pack_length() <
 
3096
          (*field)->pack_length())
 
3097
        pos= i;
 
3098
    }
 
3099
  }
 
3100
  return (pos);
 
3101
}
 
3102
 
 
3103
 
 
3104
        /* Check that the integer is in the internal */
 
3105
 
 
3106
int set_zone(register int nr, int min_zone, int max_zone)
 
3107
{
 
3108
  if (nr<=min_zone)
 
3109
    return (min_zone);
 
3110
  if (nr>=max_zone)
 
3111
    return (max_zone);
 
3112
  return (nr);
 
3113
} /* set_zone */
 
3114
 
 
3115
        /* Adjust number to next larger disk buffer */
 
3116
 
 
3117
ulong next_io_size(register ulong pos)
 
3118
{
 
3119
  reg2 ulong offset;
 
3120
  if ((offset= pos & (IO_SIZE-1)))
 
3121
    return pos-offset+IO_SIZE;
 
3122
  return pos;
 
3123
} /* next_io_size */
 
3124
 
 
3125
 
 
3126
/*
 
3127
  Store an SQL quoted string.
 
3128
 
 
3129
  SYNOPSIS  
 
3130
    append_unescaped()
 
3131
    res         result String
 
3132
    pos         string to be quoted
 
3133
    length      it's length
 
3134
 
 
3135
  NOTE
 
3136
    This function works correctly with utf8 or single-byte charset strings.
 
3137
    May fail with some multibyte charsets though.
 
3138
*/
 
3139
 
 
3140
void append_unescaped(String *res, const char *pos, uint length)
 
3141
{
 
3142
  const char *end= pos+length;
 
3143
  res->append('\'');
 
3144
 
 
3145
  for (; pos != end ; pos++)
 
3146
  {
 
3147
#if defined(USE_MB) && MYSQL_VERSION_ID < 40100
 
3148
    uint mblen;
 
3149
    if (use_mb(default_charset_info) &&
 
3150
        (mblen= my_ismbchar(default_charset_info, pos, end)))
 
3151
    {
 
3152
      res->append(pos, mblen);
 
3153
      pos+= mblen;
 
3154
      continue;
 
3155
    }
 
3156
#endif
 
3157
 
 
3158
    switch (*pos) {
 
3159
    case 0:                             /* Must be escaped for 'mysql' */
 
3160
      res->append('\\');
 
3161
      res->append('0');
 
3162
      break;
 
3163
    case '\n':                          /* Must be escaped for logs */
 
3164
      res->append('\\');
 
3165
      res->append('n');
 
3166
      break;
 
3167
    case '\r':
 
3168
      res->append('\\');                /* This gives better readability */
 
3169
      res->append('r');
 
3170
      break;
 
3171
    case '\\':
 
3172
      res->append('\\');                /* Because of the sql syntax */
 
3173
      res->append('\\');
 
3174
      break;
 
3175
    case '\'':
 
3176
      res->append('\'');                /* Because of the sql syntax */
 
3177
      res->append('\'');
 
3178
      break;
 
3179
    default:
 
3180
      res->append(*pos);
 
3181
      break;
 
3182
    }
 
3183
  }
 
3184
  res->append('\'');
 
3185
}
 
3186
 
 
3187
 
 
3188
        /* Create a .frm file */
 
3189
 
 
3190
File create_frm(THD *thd, const char *name, const char *db,
 
3191
                const char *table, uint reclength, uchar *fileinfo,
 
3192
                HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
 
3193
{
 
3194
  register File file;
 
3195
  ulong length;
 
3196
  uchar fill[IO_SIZE];
 
3197
  int create_flags= O_RDWR | O_TRUNC;
 
3198
  ulong key_comment_total_bytes= 0;
 
3199
  uint i;
 
3200
  DBUG_ENTER("create_frm");
 
3201
 
 
3202
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
3203
    create_flags|= O_EXCL | O_NOFOLLOW;
 
3204
 
 
3205
  /* Fix this when we have new .frm files;  Current limit is 4G rows (TODO) */
 
3206
  if (create_info->max_rows > UINT_MAX32)
 
3207
    create_info->max_rows= UINT_MAX32;
 
3208
  if (create_info->min_rows > UINT_MAX32)
 
3209
    create_info->min_rows= UINT_MAX32;
 
3210
 
 
3211
  if ((file= mysql_file_create(key_file_frm,
 
3212
                               name, CREATE_MODE, create_flags, MYF(0))) >= 0)
 
3213
  {
 
3214
    uint key_length, tmp_key_length, tmp, csid;
 
3215
    bzero((char*) fileinfo,64);
 
3216
    /* header */
 
3217
    fileinfo[0]=(uchar) 254;
 
3218
    fileinfo[1]= 1;
 
3219
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
 
3220
 
 
3221
    fileinfo[3]= (uchar) ha_legacy_type(
 
3222
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
 
3223
    fileinfo[4]=1;
 
3224
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
 
3225
    /*
 
3226
      Keep in sync with pack_keys() in unireg.cc
 
3227
      For each key:
 
3228
      8 bytes for the key header
 
3229
      9 bytes for each key-part (MAX_REF_PARTS)
 
3230
      NAME_LEN bytes for the name
 
3231
      1 byte for the NAMES_SEP_CHAR (before the name)
 
3232
      For all keys:
 
3233
      6 bytes for the header
 
3234
      1 byte for the NAMES_SEP_CHAR (after the last name)
 
3235
      9 extra bytes (padding for safety? alignment?)
 
3236
    */
 
3237
    for (i= 0; i < keys; i++)
 
3238
    {
 
3239
      DBUG_ASSERT(test(key_info[i].flags & HA_USES_COMMENT) == 
 
3240
                 (key_info[i].comment.length > 0));
 
3241
      if (key_info[i].flags & HA_USES_COMMENT)
 
3242
        key_comment_total_bytes += 2 + key_info[i].comment.length;
 
3243
    }
 
3244
 
 
3245
    key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16
 
3246
                + key_comment_total_bytes;
 
3247
 
 
3248
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
 
3249
                                  create_info->extra_size));
 
3250
    int4store(fileinfo+10,length);
 
3251
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
 
3252
    int2store(fileinfo+14,tmp_key_length);
 
3253
    int2store(fileinfo+16,reclength);
 
3254
    int4store(fileinfo+18,create_info->max_rows);
 
3255
    int4store(fileinfo+22,create_info->min_rows);
 
3256
    /* fileinfo[26] is set in mysql_create_frm() */
 
3257
    fileinfo[27]=2;                             // Use long pack-fields
 
3258
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
 
3259
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
 
3260
    int2store(fileinfo+30,create_info->table_options);
 
3261
    fileinfo[32]=0;                             // No filename anymore
 
3262
    fileinfo[33]=5;                             // Mark for 5.0 frm file
 
3263
    int4store(fileinfo+34,create_info->avg_row_length);
 
3264
    csid= (create_info->default_table_charset ?
 
3265
           create_info->default_table_charset->number : 0);
 
3266
    fileinfo[38]= (uchar) csid;
 
3267
    fileinfo[39]= (uchar) ((uint) create_info->transactional |
 
3268
                           ((uint) create_info->page_checksum << 2));
 
3269
    fileinfo[40]= (uchar) create_info->row_type;
 
3270
    /* Next few bytes where for RAID support */
 
3271
    fileinfo[41]= (uchar) (csid >> 8);
 
3272
    fileinfo[42]= 0;
 
3273
    fileinfo[43]= 0;
 
3274
    fileinfo[44]= 0;
 
3275
    fileinfo[45]= 0;
 
3276
    fileinfo[46]= 0;
 
3277
    int4store(fileinfo+47, key_length);
 
3278
    tmp= MYSQL_VERSION_ID;          // Store to avoid warning from int4store
 
3279
    int4store(fileinfo+51, tmp);
 
3280
    int4store(fileinfo+55, create_info->extra_size);
 
3281
    /*
 
3282
      59-60 is reserved for extra_rec_buf_length,
 
3283
      61 for default_part_db_type
 
3284
    */
 
3285
    int2store(fileinfo+62, create_info->key_block_size);
 
3286
    bzero(fill,IO_SIZE);
 
3287
    for (; length > IO_SIZE ; length-= IO_SIZE)
 
3288
    {
 
3289
      if (mysql_file_write(file, fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
 
3290
      {
 
3291
        (void) mysql_file_close(file, MYF(0));
 
3292
        (void) mysql_file_delete(key_file_frm, name, MYF(0));
 
3293
        return(-1);
 
3294
      }
 
3295
    }
 
3296
  }
 
3297
  else
 
3298
  {
 
3299
    if (my_errno == ENOENT)
 
3300
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
3301
    else
 
3302
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
 
3303
  }
 
3304
  DBUG_RETURN(file);
 
3305
} /* create_frm */
 
3306
 
 
3307
 
 
3308
void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
 
3309
{
 
3310
  TABLE_SHARE *share= table->s;
 
3311
  DBUG_ENTER("update_create_info_from_table");
 
3312
 
 
3313
  create_info->max_rows= share->max_rows;
 
3314
  create_info->min_rows= share->min_rows;
 
3315
  create_info->table_options= share->db_create_options;
 
3316
  create_info->avg_row_length= share->avg_row_length;
 
3317
  create_info->row_type= share->row_type;
 
3318
  create_info->default_table_charset= share->table_charset;
 
3319
  create_info->table_charset= 0;
 
3320
  create_info->comment= share->comment;
 
3321
  create_info->transactional= share->transactional;
 
3322
  create_info->page_checksum= share->page_checksum;
 
3323
  create_info->option_list= share->option_list;
 
3324
 
 
3325
  DBUG_VOID_RETURN;
 
3326
}
 
3327
 
 
3328
int
 
3329
rename_file_ext(const char * from,const char * to,const char * ext)
 
3330
{
 
3331
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
 
3332
  (void) strxmov(from_b,from,ext,NullS);
 
3333
  (void) strxmov(to_b,to,ext,NullS);
 
3334
  return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(MY_WME)));
 
3335
}
 
3336
 
 
3337
 
 
3338
/*
 
3339
  Allocate string field in MEM_ROOT and return it as String
 
3340
 
 
3341
  SYNOPSIS
 
3342
    get_field()
 
3343
    mem         MEM_ROOT for allocating
 
3344
    field       Field for retrieving of string
 
3345
    res         result String
 
3346
 
 
3347
  RETURN VALUES
 
3348
    1   string is empty
 
3349
    0   all ok
 
3350
*/
 
3351
 
 
3352
bool get_field(MEM_ROOT *mem, Field *field, String *res)
 
3353
{
 
3354
  char buff[MAX_FIELD_WIDTH], *to;
 
3355
  String str(buff,sizeof(buff),&my_charset_bin);
 
3356
  uint length;
 
3357
 
 
3358
  field->val_str(&str);
 
3359
  if (!(length= str.length()))
 
3360
  {
 
3361
    res->length(0);
 
3362
    return 1;
 
3363
  }
 
3364
  if (!(to= strmake_root(mem, str.ptr(), length)))
 
3365
    length= 0;                                  // Safety fix
 
3366
  res->set(to, length, ((Field_str*)field)->charset());
 
3367
  return 0;
 
3368
}
 
3369
 
 
3370
 
 
3371
/*
 
3372
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
 
3373
 
 
3374
  SYNOPSIS
 
3375
    get_field()
 
3376
    mem         MEM_ROOT for allocating
 
3377
    field       Field for retrieving of string
 
3378
 
 
3379
  RETURN VALUES
 
3380
    NullS  string is empty
 
3381
    #      pointer to NULL-terminated string value of field
 
3382
*/
 
3383
 
 
3384
char *get_field(MEM_ROOT *mem, Field *field)
 
3385
{
 
3386
  char buff[MAX_FIELD_WIDTH], *to;
 
3387
  String str(buff,sizeof(buff),&my_charset_bin);
 
3388
  uint length;
 
3389
 
 
3390
  field->val_str(&str);
 
3391
  length= str.length();
 
3392
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
 
3393
    return NullS;
 
3394
  memcpy(to,str.ptr(),(uint) length);
 
3395
  to[length]=0;
 
3396
  return to;
 
3397
}
 
3398
 
 
3399
/*
 
3400
  DESCRIPTION
 
3401
    given a buffer with a key value, and a map of keyparts
 
3402
    that are present in this value, returns the length of the value
 
3403
*/
 
3404
uint calculate_key_len(TABLE *table, uint key, const uchar *buf,
 
3405
                       key_part_map keypart_map)
 
3406
{
 
3407
  /* works only with key prefixes */
 
3408
  DBUG_ASSERT(((keypart_map + 1) & keypart_map) == 0);
 
3409
 
 
3410
  KEY *key_info= table->s->key_info+key;
 
3411
  KEY_PART_INFO *key_part= key_info->key_part;
 
3412
  KEY_PART_INFO *end_key_part= key_part + table->actual_n_key_parts(key_info);
 
3413
  uint length= 0;
 
3414
 
 
3415
  while (key_part < end_key_part && keypart_map)
 
3416
  {
 
3417
    length+= key_part->store_length;
 
3418
    keypart_map >>= 1;
 
3419
    key_part++;
 
3420
  }
 
3421
  return length;
 
3422
}
 
3423
 
 
3424
/*
 
3425
  Check if database name is valid
 
3426
 
 
3427
  SYNPOSIS
 
3428
    check_db_name()
 
3429
    org_name            Name of database and length
 
3430
 
 
3431
  NOTES
 
3432
    If lower_case_table_names is set then database is converted to lower case
 
3433
 
 
3434
  RETURN
 
3435
    0   ok
 
3436
    1   error
 
3437
*/
 
3438
 
 
3439
bool check_db_name(LEX_STRING *org_name)
 
3440
{
 
3441
  char *name= org_name->str;
 
3442
  uint name_length= org_name->length;
 
3443
  bool check_for_path_chars;
 
3444
 
 
3445
  if ((check_for_path_chars= check_mysql50_prefix(name)))
 
3446
  {
 
3447
    name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
3448
    name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
3449
  }
 
3450
 
 
3451
  if (!name_length || name_length > NAME_LEN)
 
3452
    return 1;
 
3453
 
 
3454
  if (lower_case_table_names && name != any_db)
 
3455
    my_casedn_str(files_charset_info, name);
 
3456
 
 
3457
  if (db_name_is_in_ignore_db_dirs_list(name))
 
3458
    return 1;
 
3459
 
 
3460
  return check_table_name(name, name_length, check_for_path_chars);
 
3461
}
 
3462
 
 
3463
 
 
3464
/*
 
3465
  Allow anything as a table name, as long as it doesn't contain an
 
3466
  ' ' at the end
 
3467
  returns 1 on error
 
3468
*/
 
3469
 
 
3470
bool check_table_name(const char *name, size_t length, bool check_for_path_chars)
 
3471
{
 
3472
  // name length in symbols
 
3473
  size_t name_length= 0;
 
3474
  const char *end= name+length;
 
3475
 
 
3476
 
 
3477
  if (!check_for_path_chars &&
 
3478
      (check_for_path_chars= check_mysql50_prefix(name)))
 
3479
  {
 
3480
    name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
3481
    length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
3482
  }
 
3483
 
 
3484
  if (!length || length > NAME_LEN)
 
3485
    return 1;
 
3486
#if defined(USE_MB) && defined(USE_MB_IDENT)
 
3487
  bool last_char_is_space= FALSE;
 
3488
#else
 
3489
  if (name[length-1]==' ')
 
3490
    return 1;
 
3491
#endif
 
3492
 
 
3493
  while (name != end)
 
3494
  {
 
3495
#if defined(USE_MB) && defined(USE_MB_IDENT)
 
3496
    last_char_is_space= my_isspace(system_charset_info, *name);
 
3497
    if (use_mb(system_charset_info))
 
3498
    {
 
3499
      int len=my_ismbchar(system_charset_info, name, end);
 
3500
      if (len)
 
3501
      {
 
3502
        name+= len;
 
3503
        name_length++;
 
3504
        continue;
 
3505
      }
 
3506
    }
 
3507
#endif
 
3508
    if (check_for_path_chars &&
 
3509
        (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
 
3510
      return 1;
 
3511
    name++;
 
3512
    name_length++;
 
3513
  }
 
3514
#if defined(USE_MB) && defined(USE_MB_IDENT)
 
3515
  return last_char_is_space || (name_length > NAME_CHAR_LEN);
 
3516
#else
 
3517
  return FALSE;
 
3518
#endif
 
3519
}
 
3520
 
 
3521
 
 
3522
bool check_column_name(const char *name)
 
3523
{
 
3524
  // name length in symbols
 
3525
  size_t name_length= 0;
 
3526
  bool last_char_is_space= TRUE;
 
3527
 
 
3528
  while (*name)
 
3529
  {
 
3530
#if defined(USE_MB) && defined(USE_MB_IDENT)
 
3531
    last_char_is_space= my_isspace(system_charset_info, *name);
 
3532
    if (use_mb(system_charset_info))
 
3533
    {
 
3534
      int len=my_ismbchar(system_charset_info, name, 
 
3535
                          name+system_charset_info->mbmaxlen);
 
3536
      if (len)
 
3537
      {
 
3538
        name += len;
 
3539
        name_length++;
 
3540
        continue;
 
3541
      }
 
3542
    }
 
3543
#else
 
3544
    last_char_is_space= *name==' ';
 
3545
    if (*name == '\377')
 
3546
      return 1;
 
3547
#endif
 
3548
    name++;
 
3549
    name_length++;
 
3550
  }
 
3551
  /* Error if empty or too long column name */
 
3552
  return last_char_is_space || (name_length > NAME_CHAR_LEN);
 
3553
}
 
3554
 
 
3555
 
 
3556
/**
 
3557
  Checks whether a table is intact. Should be done *just* after the table has
 
3558
  been opened.
 
3559
 
 
3560
  @param[in] table             The table to check
 
3561
  @param[in] table_f_count     Expected number of columns in the table
 
3562
  @param[in] table_def         Expected structure of the table (column name
 
3563
                               and type)
 
3564
 
 
3565
  @retval  FALSE  OK
 
3566
  @retval  TRUE   There was an error. An error message is output
 
3567
                  to the error log.  We do not push an error
 
3568
                  message into the error stack because this
 
3569
                  function is currently only called at start up,
 
3570
                  and such errors never reach the user.
 
3571
*/
 
3572
 
 
3573
bool
 
3574
Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
 
3575
{
 
3576
  uint i;
 
3577
  my_bool error= FALSE;
 
3578
  const TABLE_FIELD_TYPE *field_def= table_def->field;
 
3579
  DBUG_ENTER("table_check_intact");
 
3580
  DBUG_PRINT("info",("table: %s  expected_count: %d",
 
3581
                     table->alias.c_ptr(), table_def->count));
 
3582
 
 
3583
  /* Whether the table definition has already been validated. */
 
3584
  if (table->s->table_field_def_cache == table_def)
 
3585
    DBUG_RETURN(FALSE);
 
3586
 
 
3587
  if (table->s->fields != table_def->count)
 
3588
  {
 
3589
    DBUG_PRINT("info", ("Column count has changed, checking the definition"));
 
3590
 
 
3591
    /* previous MySQL version */
 
3592
    if (MYSQL_VERSION_ID > table->s->mysql_version)
 
3593
    {
 
3594
      report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE,
 
3595
                   ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
3596
                   table->alias.c_ptr(), table_def->count, table->s->fields,
 
3597
                   static_cast<int>(table->s->mysql_version),
 
3598
                   MYSQL_VERSION_ID);
 
3599
      DBUG_RETURN(TRUE);
 
3600
    }
 
3601
    else if (MYSQL_VERSION_ID == table->s->mysql_version)
 
3602
    {
 
3603
      report_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED,
 
3604
                   ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED),
 
3605
                   table->alias.c_ptr(),
 
3606
                   table_def->count, table->s->fields);
 
3607
      DBUG_RETURN(TRUE);
 
3608
    }
 
3609
    /*
 
3610
      Something has definitely changed, but we're running an older
 
3611
      version of MySQL with new system tables.
 
3612
      Let's check column definitions. If a column was added at
 
3613
      the end of the table, then we don't care much since such change
 
3614
      is backward compatible.
 
3615
    */
 
3616
  }
 
3617
  char buffer[1024];
 
3618
  for (i=0 ; i < table_def->count; i++, field_def++)
 
3619
  {
 
3620
    String sql_type(buffer, sizeof(buffer), system_charset_info);
 
3621
    sql_type.length(0);
 
3622
    /* Allocate min 256 characters at once */
 
3623
    sql_type.extra_allocation(256);
 
3624
    if (i < table->s->fields)
 
3625
    {
 
3626
      Field *field= table->field[i];
 
3627
 
 
3628
      if (strncmp(field->field_name, field_def->name.str,
 
3629
                  field_def->name.length))
 
3630
      {
 
3631
        /*
 
3632
          Name changes are not fatal, we use ordinal numbers to access columns.
 
3633
          Still this can be a sign of a tampered table, output an error
 
3634
          to the error log.
 
3635
        */
 
3636
        report_error(0, "Incorrect definition of table %s.%s: "
 
3637
                     "expected column '%s' at position %d, found '%s'.",
 
3638
                     table->s->db.str, table->alias.c_ptr(),
 
3639
                     field_def->name.str, i,
 
3640
                     field->field_name);
 
3641
      }
 
3642
      field->sql_type(sql_type);
 
3643
      /*
 
3644
        Generally, if column types don't match, then something is
 
3645
        wrong.
 
3646
 
 
3647
        However, we only compare column definitions up to the
 
3648
        length of the original definition, since we consider the
 
3649
        following definitions compatible:
 
3650
 
 
3651
        1. DATETIME and DATETIM
 
3652
        2. INT(11) and INT(11
 
3653
        3. SET('one', 'two') and SET('one', 'two', 'more')
 
3654
 
 
3655
        For SETs or ENUMs, if the same prefix is there it's OK to
 
3656
        add more elements - they will get higher ordinal numbers and
 
3657
        the new table definition is backward compatible with the
 
3658
        original one.
 
3659
       */
 
3660
      if (strncmp(sql_type.c_ptr_safe(), field_def->type.str,
 
3661
                  field_def->type.length - 1))
 
3662
      {
 
3663
        report_error(0, "Incorrect definition of table %s.%s: "
 
3664
                     "expected column '%s' at position %d to have type "
 
3665
                     "%s, found type %s.", table->s->db.str,
 
3666
                     table->alias.c_ptr(),
 
3667
                     field_def->name.str, i, field_def->type.str,
 
3668
                     sql_type.c_ptr_safe());
 
3669
        error= TRUE;
 
3670
      }
 
3671
      else if (field_def->cset.str && !field->has_charset())
 
3672
      {
 
3673
        report_error(0, "Incorrect definition of table %s.%s: "
 
3674
                     "expected the type of column '%s' at position %d "
 
3675
                     "to have character set '%s' but the type has no "
 
3676
                     "character set.", table->s->db.str,
 
3677
                     table->alias.c_ptr(),
 
3678
                     field_def->name.str, i, field_def->cset.str);
 
3679
        error= TRUE;
 
3680
      }
 
3681
      else if (field_def->cset.str &&
 
3682
               strcmp(field->charset()->csname, field_def->cset.str))
 
3683
      {
 
3684
        report_error(0, "Incorrect definition of table %s.%s: "
 
3685
                     "expected the type of column '%s' at position %d "
 
3686
                     "to have character set '%s' but found "
 
3687
                     "character set '%s'.", table->s->db.str,
 
3688
                     table->alias.c_ptr(),
 
3689
                     field_def->name.str, i, field_def->cset.str,
 
3690
                     field->charset()->csname);
 
3691
        error= TRUE;
 
3692
      }
 
3693
    }
 
3694
    else
 
3695
    {
 
3696
      report_error(0, "Incorrect definition of table %s.%s: "
 
3697
                   "expected column '%s' at position %d to have type %s "
 
3698
                   " but the column is not found.",
 
3699
                   table->s->db.str, table->alias.c_ptr(),
 
3700
                   field_def->name.str, i, field_def->type.str);
 
3701
      error= TRUE;
 
3702
    }
 
3703
  }
 
3704
 
 
3705
  if (! error)
 
3706
    table->s->table_field_def_cache= table_def;
 
3707
 
 
3708
  DBUG_RETURN(error);
 
3709
}
 
3710
 
 
3711
 
 
3712
/**
 
3713
  Traverse portion of wait-for graph which is reachable through edge
 
3714
  represented by this flush ticket in search for deadlocks.
 
3715
 
 
3716
  @retval TRUE  A deadlock is found. A victim is remembered
 
3717
                by the visitor.
 
3718
  @retval FALSE Success, no deadlocks.
 
3719
*/
 
3720
 
 
3721
bool Wait_for_flush::accept_visitor(MDL_wait_for_graph_visitor *gvisitor)
 
3722
{
 
3723
  return m_share->visit_subgraph(this, gvisitor);
 
3724
}
 
3725
 
 
3726
 
 
3727
uint Wait_for_flush::get_deadlock_weight() const
 
3728
{
 
3729
  return m_deadlock_weight;
 
3730
}
 
3731
 
 
3732
 
 
3733
/**
 
3734
  Traverse portion of wait-for graph which is reachable through this
 
3735
  table share in search for deadlocks.
 
3736
 
 
3737
  @param waiting_ticket  Ticket representing wait for this share.
 
3738
  @param dvisitor        Deadlock detection visitor.
 
3739
 
 
3740
  @retval TRUE  A deadlock is found. A victim is remembered
 
3741
                by the visitor.
 
3742
  @retval FALSE No deadlocks, it's OK to begin wait.
 
3743
*/
 
3744
 
 
3745
bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
 
3746
                                 MDL_wait_for_graph_visitor *gvisitor)
 
3747
{
 
3748
  TABLE *table;
 
3749
  MDL_context *src_ctx= wait_for_flush->get_ctx();
 
3750
  bool result= TRUE;
 
3751
 
 
3752
  /*
 
3753
    To protect used_tables list from being concurrently modified
 
3754
    while we are iterating through it we acquire LOCK_open.
 
3755
    This does not introduce deadlocks in the deadlock detector
 
3756
    because we won't try to acquire LOCK_open while
 
3757
    holding a write-lock on MDL_lock::m_rwlock.
 
3758
  */
 
3759
  if (gvisitor->m_lock_open_count++ == 0)
 
3760
    mysql_mutex_lock(&LOCK_open);
 
3761
 
 
3762
  I_P_List_iterator <TABLE, TABLE_share> tables_it(used_tables);
 
3763
 
 
3764
  /*
 
3765
    In case of multiple searches running in parallel, avoid going
 
3766
    over the same loop twice and shortcut the search.
 
3767
    Do it after taking the lock to weed out unnecessary races.
 
3768
  */
 
3769
  if (src_ctx->m_wait.get_status() != MDL_wait::EMPTY)
 
3770
  {
 
3771
    result= FALSE;
 
3772
    goto end;
 
3773
  }
 
3774
 
 
3775
  if (gvisitor->enter_node(src_ctx))
 
3776
    goto end;
 
3777
 
 
3778
  while ((table= tables_it++))
 
3779
  {
 
3780
    if (gvisitor->inspect_edge(&table->in_use->mdl_context))
 
3781
    {
 
3782
      goto end_leave_node;
 
3783
    }
 
3784
  }
 
3785
 
 
3786
  tables_it.rewind();
 
3787
  while ((table= tables_it++))
 
3788
  {
 
3789
    if (table->in_use->mdl_context.visit_subgraph(gvisitor))
 
3790
    {
 
3791
      goto end_leave_node;
 
3792
    }
 
3793
  }
 
3794
 
 
3795
  result= FALSE;
 
3796
 
 
3797
end_leave_node:
 
3798
  gvisitor->leave_node(src_ctx);
 
3799
 
 
3800
end:
 
3801
  if (gvisitor->m_lock_open_count-- == 1)
 
3802
    mysql_mutex_unlock(&LOCK_open);
 
3803
 
 
3804
  return result;
 
3805
}
 
3806
 
 
3807
 
 
3808
/**
 
3809
  Wait until the subject share is removed from the table
 
3810
  definition cache and make sure it's destroyed.
 
3811
 
 
3812
  @param mdl_context     MDL context for thread which is going to wait.
 
3813
  @param abstime         Timeout for waiting as absolute time value.
 
3814
  @param deadlock_weight Weight of this wait for deadlock detector.
 
3815
 
 
3816
  @pre LOCK_open is write locked, the share is used (has
 
3817
       non-zero reference count), is marked for flush and
 
3818
       this connection does not reference the share.
 
3819
       LOCK_open will be unlocked temporarily during execution.
 
3820
 
 
3821
  @retval FALSE - Success.
 
3822
  @retval TRUE  - Error (OOM, deadlock, timeout, etc...).
 
3823
*/
 
3824
 
 
3825
bool TABLE_SHARE::wait_for_old_version(THD *thd, struct timespec *abstime,
 
3826
                                       uint deadlock_weight)
 
3827
{
 
3828
  MDL_context *mdl_context= &thd->mdl_context;
 
3829
  Wait_for_flush ticket(mdl_context, this, deadlock_weight);
 
3830
  MDL_wait::enum_wait_status wait_status;
 
3831
 
 
3832
  mysql_mutex_assert_owner(&LOCK_open);
 
3833
  /*
 
3834
    We should enter this method only when share's version is not
 
3835
    up to date and the share is referenced. Otherwise our
 
3836
    thread will never be woken up from wait.
 
3837
  */
 
3838
  DBUG_ASSERT(version != refresh_version && ref_count != 0);
 
3839
 
 
3840
  m_flush_tickets.push_front(&ticket);
 
3841
 
 
3842
  mdl_context->m_wait.reset_status();
 
3843
 
 
3844
  mysql_mutex_unlock(&LOCK_open);
 
3845
 
 
3846
  mdl_context->will_wait_for(&ticket);
 
3847
 
 
3848
  mdl_context->find_deadlock();
 
3849
 
 
3850
  wait_status= mdl_context->m_wait.timed_wait(thd, abstime, TRUE,
 
3851
                                              "Waiting for table flush");
 
3852
 
 
3853
  mdl_context->done_waiting_for();
 
3854
 
 
3855
  mysql_mutex_lock(&LOCK_open);
 
3856
 
 
3857
  m_flush_tickets.remove(&ticket);
 
3858
 
 
3859
  if (m_flush_tickets.is_empty() && ref_count == 0)
 
3860
  {
 
3861
    /*
 
3862
      If our thread was the last one using the share,
 
3863
      we must destroy it here.
 
3864
    */
 
3865
    destroy();
 
3866
  }
 
3867
 
 
3868
  /*
 
3869
    In cases when our wait was aborted by KILL statement,
 
3870
    a deadlock or a timeout, the share might still be referenced,
 
3871
    so we don't delete it. Note, that we can't determine this
 
3872
    condition by checking wait_status alone, since, for example,
 
3873
    a timeout can happen after all references to the table share
 
3874
    were released, but before the share is removed from the
 
3875
    cache and we receive the notification. This is why
 
3876
    we first destroy the share, and then look at
 
3877
    wait_status.
 
3878
  */
 
3879
  switch (wait_status)
 
3880
  {
 
3881
  case MDL_wait::GRANTED:
 
3882
    return FALSE;
 
3883
  case MDL_wait::VICTIM:
 
3884
    my_error(ER_LOCK_DEADLOCK, MYF(0));
 
3885
    return TRUE;
 
3886
  case MDL_wait::TIMEOUT:
 
3887
    my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
 
3888
    return TRUE;
 
3889
  case MDL_wait::KILLED:
 
3890
    return TRUE;
 
3891
  default:
 
3892
    DBUG_ASSERT(0);
 
3893
    return TRUE;
 
3894
  }
 
3895
}
 
3896
 
 
3897
 
 
3898
/**
 
3899
  Initialize TABLE instance (newly created, or coming either from table
 
3900
  cache or THD::temporary_tables list) and prepare it for further use
 
3901
  during statement execution. Set the 'alias' attribute from the specified
 
3902
  TABLE_LIST element. Remember the TABLE_LIST element in the
 
3903
  TABLE::pos_in_table_list member.
 
3904
 
 
3905
  @param thd  Thread context.
 
3906
  @param tl   TABLE_LIST element.
 
3907
*/
 
3908
 
 
3909
void TABLE::init(THD *thd, TABLE_LIST *tl)
 
3910
{
 
3911
  DBUG_ASSERT(s->ref_count > 0 || s->tmp_table != NO_TMP_TABLE);
 
3912
 
 
3913
  if (thd->lex->need_correct_ident())
 
3914
    alias_name_used= my_strcasecmp(table_alias_charset,
 
3915
                                   s->table_name.str,
 
3916
                                   tl->alias);
 
3917
  /* Fix alias if table name changes. */
 
3918
  if (strcmp(alias.c_ptr(), tl->alias))
 
3919
    alias.copy(tl->alias, strlen(tl->alias), alias.charset());
 
3920
 
 
3921
  tablenr= thd->current_tablenr++;
 
3922
  used_fields= 0;
 
3923
  const_table= 0;
 
3924
  null_row= 0;
 
3925
  maybe_null= 0;
 
3926
  force_index= 0;
 
3927
  force_index_order= 0;
 
3928
  force_index_group= 0;
 
3929
  status= STATUS_NO_RECORD;
 
3930
  insert_values= 0;
 
3931
  fulltext_searched= 0;
 
3932
  file->ha_start_of_new_statement();
 
3933
  reginfo.impossible_range= 0;
 
3934
  created= TRUE;
 
3935
 
 
3936
  /* Catch wrong handling of the auto_increment_field_not_null. */
 
3937
  DBUG_ASSERT(!auto_increment_field_not_null);
 
3938
  auto_increment_field_not_null= FALSE;
 
3939
 
 
3940
  if (timestamp_field)
 
3941
    timestamp_field_type= timestamp_field->get_auto_set_type();
 
3942
 
 
3943
  pos_in_table_list= tl;
 
3944
 
 
3945
  clear_column_bitmaps();
 
3946
 
 
3947
  DBUG_ASSERT(key_read == 0);
 
3948
 
 
3949
  /* mark the record[0] uninitialized */
 
3950
  TRASH(record[0], s->reclength);
 
3951
 
 
3952
  /*
 
3953
    Initialize the null marker bits, to ensure that if we are doing a read
 
3954
    of only selected columns (like in keyread), all null markers are
 
3955
    initialized.
 
3956
  */
 
3957
  memset(record[0], 255, s->null_bytes); 
 
3958
  memset(record[1], 255, s->null_bytes); 
 
3959
 
 
3960
  /* Tables may be reused in a sub statement. */
 
3961
  DBUG_ASSERT(!file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN));
 
3962
}
 
3963
 
 
3964
 
 
3965
/*
 
3966
  Create Item_field for each column in the table.
 
3967
 
 
3968
  SYNPOSIS
 
3969
    TABLE::fill_item_list()
 
3970
      item_list          a pointer to an empty list used to store items
 
3971
 
 
3972
  DESCRIPTION
 
3973
    Create Item_field object for each column in the table and
 
3974
    initialize it with the corresponding Field. New items are
 
3975
    created in the current THD memory root.
 
3976
 
 
3977
  RETURN VALUE
 
3978
    0                    success
 
3979
    1                    out of memory
 
3980
*/
 
3981
 
 
3982
bool TABLE::fill_item_list(List<Item> *item_list) const
 
3983
{
 
3984
  /*
 
3985
    All Item_field's created using a direct pointer to a field
 
3986
    are fixed in Item_field constructor.
 
3987
  */
 
3988
  for (Field **ptr= field; *ptr; ptr++)
 
3989
  {
 
3990
    Item_field *item= new Item_field(*ptr);
 
3991
    if (!item || item_list->push_back(item))
 
3992
      return TRUE;
 
3993
  }
 
3994
  return FALSE;
 
3995
}
 
3996
 
 
3997
/*
 
3998
  Reset an existing list of Item_field items to point to the
 
3999
  Fields of this table.
 
4000
 
 
4001
  SYNPOSIS
 
4002
    TABLE::fill_item_list()
 
4003
      item_list          a non-empty list with Item_fields
 
4004
 
 
4005
  DESCRIPTION
 
4006
    This is a counterpart of fill_item_list used to redirect
 
4007
    Item_fields to the fields of a newly created table.
 
4008
    The caller must ensure that number of items in the item_list
 
4009
    is the same as the number of columns in the table.
 
4010
*/
 
4011
 
 
4012
void TABLE::reset_item_list(List<Item> *item_list) const
 
4013
{
 
4014
  List_iterator_fast<Item> it(*item_list);
 
4015
  for (Field **ptr= field; *ptr; ptr++)
 
4016
  {
 
4017
    Item_field *item_field= (Item_field*) it++;
 
4018
    DBUG_ASSERT(item_field != 0);
 
4019
    item_field->reset_field(*ptr);
 
4020
  }
 
4021
}
 
4022
 
 
4023
/*
 
4024
  calculate md5 of query
 
4025
 
 
4026
  SYNOPSIS
 
4027
    TABLE_LIST::calc_md5()
 
4028
    buffer      buffer for md5 writing
 
4029
*/
 
4030
 
 
4031
void  TABLE_LIST::calc_md5(char *buffer)
 
4032
{
 
4033
  uchar digest[16];
 
4034
  MY_MD5_HASH(digest, (uchar *) select_stmt.str, select_stmt.length);
 
4035
  sprintf((char *) buffer,
 
4036
            "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
 
4037
            digest[0], digest[1], digest[2], digest[3],
 
4038
            digest[4], digest[5], digest[6], digest[7],
 
4039
            digest[8], digest[9], digest[10], digest[11],
 
4040
            digest[12], digest[13], digest[14], digest[15]);
 
4041
}
 
4042
 
 
4043
 
 
4044
/**
 
4045
  @brief
 
4046
  Create field translation for mergeable derived table/view.
 
4047
 
 
4048
  @param thd  Thread handle
 
4049
 
 
4050
  @details
 
4051
  Create field translation for mergeable derived table/view.
 
4052
 
 
4053
  @return FALSE ok.
 
4054
  @return TRUE an error occur.
 
4055
*/
 
4056
 
 
4057
bool TABLE_LIST::create_field_translation(THD *thd)
 
4058
{
 
4059
  Item *item;
 
4060
  Field_translator *transl;
 
4061
  SELECT_LEX *select= get_single_select();
 
4062
  List_iterator_fast<Item> it(select->item_list);
 
4063
  uint field_count= 0;
 
4064
  Query_arena *arena= thd->stmt_arena, backup;
 
4065
  bool res= FALSE;
 
4066
 
 
4067
  if (thd->stmt_arena->is_conventional() ||
 
4068
      thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
 
4069
  {
 
4070
    /* initialize lists */
 
4071
    used_items.empty();
 
4072
    persistent_used_items.empty();
 
4073
  }
 
4074
  else
 
4075
  {
 
4076
    /*
 
4077
      Copy the list created by natural join procedure because the procedure
 
4078
      will not be repeated.
 
4079
    */
 
4080
    used_items= persistent_used_items;
 
4081
  }
 
4082
 
 
4083
  if (field_translation)
 
4084
  {
 
4085
    /*
 
4086
      Update items in the field translation aftet view have been prepared.
 
4087
      It's needed because some items in the select list, like IN subselects,
 
4088
      might be substituted for optimized ones.
 
4089
    */
 
4090
    if (is_view() && get_unit()->prepared && !field_translation_updated)
 
4091
    {
 
4092
      while ((item= it++))
 
4093
      {
 
4094
        field_translation[field_count++].item= item;
 
4095
      }
 
4096
      field_translation_updated= TRUE;
 
4097
    }
 
4098
 
 
4099
    return FALSE;
 
4100
  }
 
4101
 
 
4102
  if (arena->is_conventional())
 
4103
    arena= 0;                                   // For easier test
 
4104
  else
 
4105
    thd->set_n_backup_active_arena(arena, &backup);
 
4106
 
 
4107
  /* Create view fields translation table */
 
4108
 
 
4109
  if (!(transl=
 
4110
        (Field_translator*)(thd->stmt_arena->
 
4111
                            alloc(select->item_list.elements *
 
4112
                                  sizeof(Field_translator)))))
 
4113
  {
 
4114
    res= TRUE;
 
4115
    goto exit;
 
4116
  }
 
4117
 
 
4118
  while ((item= it++))
 
4119
  {
 
4120
    transl[field_count].name= item->name;
 
4121
    transl[field_count++].item= item;
 
4122
  }
 
4123
  field_translation= transl;
 
4124
  field_translation_end= transl + field_count;
 
4125
 
 
4126
exit:
 
4127
  if (arena)
 
4128
    thd->restore_active_arena(arena, &backup);
 
4129
 
 
4130
  return res;
 
4131
}
 
4132
 
 
4133
 
 
4134
/**
 
4135
  @brief
 
4136
  Create field translation for mergeable derived table/view.
 
4137
 
 
4138
  @param thd  Thread handle
 
4139
 
 
4140
  @details
 
4141
  Create field translation for mergeable derived table/view.
 
4142
 
 
4143
  @return FALSE ok.
 
4144
  @return TRUE an error occur.
 
4145
*/
 
4146
 
 
4147
bool TABLE_LIST::setup_underlying(THD *thd)
 
4148
{
 
4149
  DBUG_ENTER("TABLE_LIST::setup_underlying");
 
4150
 
 
4151
  if (!view || (!field_translation && merge_underlying_list))
 
4152
  {
 
4153
    SELECT_LEX *select= get_single_select();
 
4154
    
 
4155
    if (create_field_translation(thd))
 
4156
      DBUG_RETURN(TRUE);
 
4157
 
 
4158
    /* full text function moving to current select */
 
4159
    if (select->ftfunc_list->elements)
 
4160
    {
 
4161
      Item_func_match *ifm;
 
4162
      SELECT_LEX *current_select= thd->lex->current_select;
 
4163
      List_iterator_fast<Item_func_match>
 
4164
        li(*(select_lex->ftfunc_list));
 
4165
      while ((ifm= li++))
 
4166
        current_select->ftfunc_list->push_front(ifm);
 
4167
    }
 
4168
  }
 
4169
  DBUG_RETURN(FALSE);
 
4170
}
 
4171
 
 
4172
 
 
4173
/*
 
4174
   Prepare where expression of derived table/view
 
4175
 
 
4176
  SYNOPSIS
 
4177
    TABLE_LIST::prep_where()
 
4178
    thd             - thread handler
 
4179
    conds           - condition of this JOIN
 
4180
    no_where_clause - do not build WHERE or ON outer qwery do not need it
 
4181
                      (it is INSERT), we do not need conds if this flag is set
 
4182
 
 
4183
  NOTE: have to be called befor CHECK OPTION preparation, because it makes
 
4184
  fix_fields for view WHERE clause
 
4185
 
 
4186
  RETURN
 
4187
    FALSE - OK
 
4188
    TRUE  - error
 
4189
*/
 
4190
 
 
4191
bool TABLE_LIST::prep_where(THD *thd, Item **conds,
 
4192
                               bool no_where_clause)
 
4193
{
 
4194
  DBUG_ENTER("TABLE_LIST::prep_where");
 
4195
  bool res= FALSE;
 
4196
 
 
4197
  for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
4198
  {
 
4199
    if (tbl->is_view_or_derived() &&
 
4200
        tbl->prep_where(thd, conds, no_where_clause))
 
4201
    {
 
4202
      DBUG_RETURN(TRUE);
 
4203
    }
 
4204
  }
 
4205
 
 
4206
  if (where)
 
4207
  {
 
4208
    if (where->fixed)
 
4209
      where->update_used_tables();
 
4210
    if (!where->fixed && where->fix_fields(thd, &where))
 
4211
    {
 
4212
      DBUG_RETURN(TRUE);
 
4213
    }
 
4214
 
 
4215
    /*
 
4216
      check that it is not VIEW in which we insert with INSERT SELECT
 
4217
      (in this case we can't add view WHERE condition to main SELECT_LEX)
 
4218
    */
 
4219
    if (!no_where_clause && !where_processed)
 
4220
    {
 
4221
      TABLE_LIST *tbl= this;
 
4222
      Query_arena *arena= thd->stmt_arena, backup;
 
4223
      arena= thd->activate_stmt_arena_if_needed(&backup);  // For easier test
 
4224
 
 
4225
      /* Go up to join tree and try to find left join */
 
4226
      for (; tbl; tbl= tbl->embedding)
 
4227
      {
 
4228
        if (tbl->outer_join)
 
4229
        {
 
4230
          /*
 
4231
            Store WHERE condition to ON expression for outer join, because
 
4232
            we can't use WHERE to correctly execute left joins on VIEWs and
 
4233
            this expression will not be moved to WHERE condition (i.e. will
 
4234
            be clean correctly for PS/SP)
 
4235
          */
 
4236
          tbl->on_expr= and_conds(tbl->on_expr,
 
4237
                                  where->copy_andor_structure(thd));
 
4238
          break;
 
4239
        }
 
4240
      }
 
4241
      if (tbl == 0)
 
4242
      {
 
4243
        if (*conds && !(*conds)->fixed)
 
4244
          res= (*conds)->fix_fields(thd, conds);
 
4245
        if (!res)
 
4246
          *conds= and_conds(*conds, where->copy_andor_structure(thd));
 
4247
        if (*conds && !(*conds)->fixed && !res)
 
4248
          res= (*conds)->fix_fields(thd, conds);
 
4249
      }
 
4250
      if (arena)
 
4251
        thd->restore_active_arena(arena, &backup);
 
4252
      where_processed= TRUE;
 
4253
    }
 
4254
  }
 
4255
 
 
4256
  DBUG_RETURN(res);
 
4257
}
 
4258
 
 
4259
/**
 
4260
  Check that table/view is updatable and if it has single
 
4261
  underlying tables/views it is also updatable
 
4262
 
 
4263
  @return Result of the check.
 
4264
*/
 
4265
 
 
4266
bool TABLE_LIST::single_table_updatable()
 
4267
{
 
4268
  if (!updatable)
 
4269
    return false;
 
4270
  if (view_tables && view_tables->elements == 1)
 
4271
  {
 
4272
    /*
 
4273
      We need to check deeply only single table views. Multi-table views
 
4274
      will be turned to multi-table updates and then checked by leaf tables
 
4275
    */
 
4276
    return view_tables->head()->single_table_updatable();
 
4277
  }
 
4278
  return true;
 
4279
}
 
4280
 
 
4281
 
 
4282
/*
 
4283
  Merge ON expressions for a view
 
4284
 
 
4285
  SYNOPSIS
 
4286
    merge_on_conds()
 
4287
    thd             thread handle
 
4288
    table           table for the VIEW
 
4289
    is_cascaded     TRUE <=> merge ON expressions from underlying views
 
4290
 
 
4291
  DESCRIPTION
 
4292
    This function returns the result of ANDing the ON expressions
 
4293
    of the given view and all underlying views. The ON expressions
 
4294
    of the underlying views are added only if is_cascaded is TRUE.
 
4295
 
 
4296
  RETURN
 
4297
    Pointer to the built expression if there is any.
 
4298
    Otherwise and in the case of a failure NULL is returned.
 
4299
*/
 
4300
 
 
4301
static Item *
 
4302
merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
 
4303
{
 
4304
  DBUG_ENTER("merge_on_conds");
 
4305
 
 
4306
  Item *cond= NULL;
 
4307
  DBUG_PRINT("info", ("alias: %s", table->alias));
 
4308
  if (table->on_expr)
 
4309
    cond= table->on_expr->copy_andor_structure(thd);
 
4310
  if (!table->view)
 
4311
    DBUG_RETURN(cond);
 
4312
  for (TABLE_LIST *tbl= (TABLE_LIST*)table->view->select_lex.table_list.first;
 
4313
       tbl;
 
4314
       tbl= tbl->next_local)
 
4315
  {
 
4316
    if (tbl->view && !is_cascaded)
 
4317
      continue;
 
4318
    cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
 
4319
  }
 
4320
  DBUG_RETURN(cond);
 
4321
}
 
4322
 
 
4323
 
 
4324
/*
 
4325
  Prepare check option expression of table
 
4326
 
 
4327
  SYNOPSIS
 
4328
    TABLE_LIST::prep_check_option()
 
4329
    thd             - thread handler
 
4330
    check_opt_type  - WITH CHECK OPTION type (VIEW_CHECK_NONE,
 
4331
                      VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
 
4332
                      we use this parameter instead of direct check of
 
4333
                      effective_with_check to change type of underlying
 
4334
                      views to VIEW_CHECK_CASCADED if outer view have
 
4335
                      such option and prevent processing of underlying
 
4336
                      view check options if outer view have just
 
4337
                      VIEW_CHECK_LOCAL option.
 
4338
 
 
4339
  NOTE
 
4340
    This method builds check option condition to use it later on
 
4341
    every call (usual execution or every SP/PS call).
 
4342
    This method have to be called after WHERE preparation
 
4343
    (TABLE_LIST::prep_where)
 
4344
 
 
4345
  RETURN
 
4346
    FALSE - OK
 
4347
    TRUE  - error
 
4348
*/
 
4349
 
 
4350
bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
 
4351
{
 
4352
  DBUG_ENTER("TABLE_LIST::prep_check_option");
 
4353
  bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
 
4354
  TABLE_LIST *merge_underlying_list= view->select_lex.get_table_list();
 
4355
  for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
4356
  {
 
4357
    /* see comment of check_opt_type parameter */
 
4358
    if (tbl->view && tbl->prep_check_option(thd, (is_cascaded ?
 
4359
                                                  VIEW_CHECK_CASCADED :
 
4360
                                                  VIEW_CHECK_NONE)))
 
4361
      DBUG_RETURN(TRUE);
 
4362
  }
 
4363
 
 
4364
  if (check_opt_type && !check_option_processed)
 
4365
  {
 
4366
    Query_arena *arena= thd->stmt_arena, backup;
 
4367
    arena= thd->activate_stmt_arena_if_needed(&backup);  // For easier test
 
4368
 
 
4369
    if (where)
 
4370
    {
 
4371
      check_option= where->copy_andor_structure(thd);
 
4372
    }
 
4373
    if (is_cascaded)
 
4374
    {
 
4375
      for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
4376
      {
 
4377
        if (tbl->check_option)
 
4378
          check_option= and_conds(check_option, tbl->check_option);
 
4379
      }
 
4380
    }
 
4381
    check_option= and_conds(check_option,
 
4382
                            merge_on_conds(thd, this, is_cascaded));
 
4383
 
 
4384
    if (arena)
 
4385
      thd->restore_active_arena(arena, &backup);
 
4386
    check_option_processed= TRUE;
 
4387
 
 
4388
  }
 
4389
 
 
4390
  if (check_option)
 
4391
  {
 
4392
    const char *save_where= thd->where;
 
4393
    thd->where= "check option";
 
4394
    if ((!check_option->fixed &&
 
4395
         check_option->fix_fields(thd, &check_option)) ||
 
4396
        check_option->check_cols(1))
 
4397
    {
 
4398
      DBUG_RETURN(TRUE);
 
4399
    }
 
4400
    thd->where= save_where;
 
4401
  }
 
4402
  DBUG_RETURN(FALSE);
 
4403
}
 
4404
 
 
4405
 
 
4406
/**
 
4407
  Hide errors which show view underlying table information. 
 
4408
  There are currently two mechanisms at work that handle errors for views,
 
4409
  this one and a more general mechanism based on an Internal_error_handler,
 
4410
  see Show_create_error_handler. The latter handles errors encountered during
 
4411
  execution of SHOW CREATE VIEW, while the mechanism using this method is
 
4412
  handles SELECT from views. The two methods should not clash.
 
4413
 
 
4414
  @param[in,out]  thd     thread handler
 
4415
 
 
4416
  @pre This method can be called only if there is an error.
 
4417
*/
 
4418
 
 
4419
void TABLE_LIST::hide_view_error(THD *thd)
 
4420
{
 
4421
  if (thd->killed || thd->get_internal_handler())
 
4422
    return;
 
4423
  /* Hide "Unknown column" or "Unknown function" error */
 
4424
  DBUG_ASSERT(thd->is_error());
 
4425
 
 
4426
  if (thd->stmt_da->sql_errno() == ER_BAD_FIELD_ERROR ||
 
4427
      thd->stmt_da->sql_errno() == ER_SP_DOES_NOT_EXIST ||
 
4428
      thd->stmt_da->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
 
4429
      thd->stmt_da->sql_errno() == ER_PROCACCESS_DENIED_ERROR ||
 
4430
      thd->stmt_da->sql_errno() == ER_COLUMNACCESS_DENIED_ERROR ||
 
4431
      thd->stmt_da->sql_errno() == ER_TABLEACCESS_DENIED_ERROR ||
 
4432
      thd->stmt_da->sql_errno() == ER_TABLE_NOT_LOCKED ||
 
4433
      thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
 
4434
  {
 
4435
    TABLE_LIST *top= top_table();
 
4436
    thd->clear_error();
 
4437
    my_error(ER_VIEW_INVALID, MYF(0), top->view_db.str, top->view_name.str);
 
4438
  }
 
4439
  else if (thd->stmt_da->sql_errno() == ER_NO_DEFAULT_FOR_FIELD)
 
4440
  {
 
4441
    TABLE_LIST *top= top_table();
 
4442
    thd->clear_error();
 
4443
    // TODO: make correct error message
 
4444
    my_error(ER_NO_DEFAULT_FOR_VIEW_FIELD, MYF(0),
 
4445
             top->view_db.str, top->view_name.str);
 
4446
  }
 
4447
}
 
4448
 
 
4449
 
 
4450
/*
 
4451
  Find underlying base tables (TABLE_LIST) which represent given
 
4452
  table_to_find (TABLE)
 
4453
 
 
4454
  SYNOPSIS
 
4455
    TABLE_LIST::find_underlying_table()
 
4456
    table_to_find table to find
 
4457
 
 
4458
  RETURN
 
4459
    0  table is not found
 
4460
    found table reference
 
4461
*/
 
4462
 
 
4463
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
 
4464
{
 
4465
  /* is this real table and table which we are looking for? */
 
4466
  if (table == table_to_find && view == 0)
 
4467
    return this;
 
4468
  if (!view)
 
4469
    return 0;
 
4470
 
 
4471
  for (TABLE_LIST *tbl= view->select_lex.get_table_list();
 
4472
       tbl;
 
4473
       tbl= tbl->next_local)
 
4474
  {
 
4475
    TABLE_LIST *result;
 
4476
    if ((result= tbl->find_underlying_table(table_to_find)))
 
4477
      return result;
 
4478
  }
 
4479
  return 0;
 
4480
}
 
4481
 
 
4482
/*
 
4483
  cleanup items belonged to view fields translation table
 
4484
 
 
4485
  SYNOPSIS
 
4486
    TABLE_LIST::cleanup_items()
 
4487
*/
 
4488
 
 
4489
void TABLE_LIST::cleanup_items()
 
4490
{
 
4491
  if (!field_translation)
 
4492
    return;
 
4493
 
 
4494
  for (Field_translator *transl= field_translation;
 
4495
       transl < field_translation_end;
 
4496
       transl++)
 
4497
    transl->item->walk(&Item::cleanup_processor, 0, 0);
 
4498
}
 
4499
 
 
4500
 
 
4501
/*
 
4502
  check CHECK OPTION condition
 
4503
 
 
4504
  SYNOPSIS
 
4505
    TABLE_LIST::view_check_option()
 
4506
    ignore_failure ignore check option fail
 
4507
 
 
4508
  RETURN
 
4509
    VIEW_CHECK_OK     OK
 
4510
    VIEW_CHECK_ERROR  FAILED
 
4511
    VIEW_CHECK_SKIP   FAILED, but continue
 
4512
*/
 
4513
 
 
4514
int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure)
 
4515
{
 
4516
  if (check_option && check_option->val_int() == 0)
 
4517
  {
 
4518
    TABLE_LIST *main_view= top_table();
 
4519
    if (ignore_failure)
 
4520
    {
 
4521
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
4522
                          ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED),
 
4523
                          main_view->view_db.str, main_view->view_name.str);
 
4524
      return(VIEW_CHECK_SKIP);
 
4525
    }
 
4526
    my_error(ER_VIEW_CHECK_FAILED, MYF(0), main_view->view_db.str,
 
4527
             main_view->view_name.str);
 
4528
    return(VIEW_CHECK_ERROR);
 
4529
  }
 
4530
  return(VIEW_CHECK_OK);
 
4531
}
 
4532
 
 
4533
 
 
4534
/*
 
4535
  Find table in underlying tables by mask and check that only this
 
4536
  table belong to given mask
 
4537
 
 
4538
  SYNOPSIS
 
4539
    TABLE_LIST::check_single_table()
 
4540
    table_arg   reference on variable where to store found table
 
4541
                (should be 0 on call, to find table, or point to table for
 
4542
                unique test)
 
4543
    map         bit mask of tables
 
4544
    view_arg    view for which we are looking table
 
4545
 
 
4546
  RETURN
 
4547
    FALSE table not found or found only one
 
4548
    TRUE  found several tables
 
4549
*/
 
4550
 
 
4551
bool TABLE_LIST::check_single_table(TABLE_LIST **table_arg,
 
4552
                                       table_map map,
 
4553
                                       TABLE_LIST *view_arg)
 
4554
{
 
4555
  if (!select_lex)
 
4556
    return FALSE;
 
4557
  DBUG_ASSERT(is_merged_derived());
 
4558
  for (TABLE_LIST *tbl= get_single_select()->get_table_list();
 
4559
       tbl;
 
4560
       tbl= tbl->next_local)
 
4561
  {
 
4562
    /*
 
4563
      Merged view has also temporary table attached (in 5.2 if it has table
 
4564
      then it was real table), so we have filter such temporary tables out
 
4565
      by checking that it is not merged view
 
4566
    */
 
4567
    if (tbl->table &&
 
4568
        !(tbl->is_view() &&
 
4569
          tbl->is_merged_derived()))
 
4570
    {
 
4571
      if (tbl->table->map & map)
 
4572
      {
 
4573
        if (*table_arg)
 
4574
          return TRUE;
 
4575
        *table_arg= tbl;
 
4576
        tbl->check_option= view_arg->check_option;
 
4577
      }
 
4578
    }
 
4579
    else if (tbl->check_single_table(table_arg, map, view_arg))
 
4580
      return TRUE;
 
4581
  }
 
4582
  return FALSE;
 
4583
}
 
4584
 
 
4585
 
 
4586
/*
 
4587
  Set insert_values buffer
 
4588
 
 
4589
  SYNOPSIS
 
4590
    set_insert_values()
 
4591
    mem_root   memory pool for allocating
 
4592
 
 
4593
  RETURN
 
4594
    FALSE - OK
 
4595
    TRUE  - out of memory
 
4596
*/
 
4597
 
 
4598
bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
 
4599
{
 
4600
  if (table)
 
4601
  {
 
4602
    if (!table->insert_values &&
 
4603
        !(table->insert_values= (uchar *)alloc_root(mem_root,
 
4604
                                                   table->s->rec_buff_length)))
 
4605
      return TRUE;
 
4606
  }
 
4607
  else
 
4608
  {
 
4609
    DBUG_ASSERT(is_view_or_derived() && is_merged_derived());
 
4610
    for (TABLE_LIST *tbl= (TABLE_LIST*)view->select_lex.table_list.first;
 
4611
         tbl;
 
4612
         tbl= tbl->next_local)
 
4613
      if (tbl->set_insert_values(mem_root))
 
4614
        return TRUE;
 
4615
  }
 
4616
  return FALSE;
 
4617
}
 
4618
 
 
4619
 
 
4620
/*
 
4621
  Test if this is a leaf with respect to name resolution.
 
4622
 
 
4623
  SYNOPSIS
 
4624
    TABLE_LIST::is_leaf_for_name_resolution()
 
4625
 
 
4626
  DESCRIPTION
 
4627
    A table reference is a leaf with respect to name resolution if
 
4628
    it is either a leaf node in a nested join tree (table, view,
 
4629
    schema table, subquery), or an inner node that represents a
 
4630
    NATURAL/USING join, or a nested join with materialized join
 
4631
    columns.
 
4632
 
 
4633
  RETURN
 
4634
    TRUE if a leaf, FALSE otherwise.
 
4635
*/
 
4636
bool TABLE_LIST::is_leaf_for_name_resolution()
 
4637
{
 
4638
  return (is_merged_derived() || is_natural_join || is_join_columns_complete ||
 
4639
          !nested_join);
 
4640
}
 
4641
 
 
4642
 
 
4643
/*
 
4644
  Retrieve the first (left-most) leaf in a nested join tree with
 
4645
  respect to name resolution.
 
4646
 
 
4647
  SYNOPSIS
 
4648
    TABLE_LIST::first_leaf_for_name_resolution()
 
4649
 
 
4650
  DESCRIPTION
 
4651
    Given that 'this' is a nested table reference, recursively walk
 
4652
    down the left-most children of 'this' until we reach a leaf
 
4653
    table reference with respect to name resolution.
 
4654
 
 
4655
  IMPLEMENTATION
 
4656
    The left-most child of a nested table reference is the last element
 
4657
    in the list of children because the children are inserted in
 
4658
    reverse order.
 
4659
 
 
4660
  RETURN
 
4661
    If 'this' is a nested table reference - the left-most child of
 
4662
      the tree rooted in 'this',
 
4663
    else return 'this'
 
4664
*/
 
4665
 
 
4666
TABLE_LIST *TABLE_LIST::first_leaf_for_name_resolution()
 
4667
{
 
4668
  TABLE_LIST *cur_table_ref;
 
4669
  NESTED_JOIN *cur_nested_join;
 
4670
  LINT_INIT(cur_table_ref);
 
4671
 
 
4672
  if (is_leaf_for_name_resolution())
 
4673
    return this;
 
4674
  DBUG_ASSERT(nested_join);
 
4675
 
 
4676
  for (cur_nested_join= nested_join;
 
4677
       cur_nested_join;
 
4678
       cur_nested_join= cur_table_ref->nested_join)
 
4679
  {
 
4680
    List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
 
4681
    cur_table_ref= it++;
 
4682
    /*
 
4683
      If the current nested join is a RIGHT JOIN, the operands in
 
4684
      'join_list' are in reverse order, thus the first operand is
 
4685
      already at the front of the list. Otherwise the first operand
 
4686
      is in the end of the list of join operands.
 
4687
    */
 
4688
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
4689
    {
 
4690
      TABLE_LIST *next;
 
4691
      while ((next= it++))
 
4692
        cur_table_ref= next;
 
4693
    }
 
4694
    if (cur_table_ref->is_leaf_for_name_resolution())
 
4695
      break;
 
4696
  }
 
4697
  return cur_table_ref;
 
4698
}
 
4699
 
 
4700
 
 
4701
/*
 
4702
  Retrieve the last (right-most) leaf in a nested join tree with
 
4703
  respect to name resolution.
 
4704
 
 
4705
  SYNOPSIS
 
4706
    TABLE_LIST::last_leaf_for_name_resolution()
 
4707
 
 
4708
  DESCRIPTION
 
4709
    Given that 'this' is a nested table reference, recursively walk
 
4710
    down the right-most children of 'this' until we reach a leaf
 
4711
    table reference with respect to name resolution.
 
4712
 
 
4713
  IMPLEMENTATION
 
4714
    The right-most child of a nested table reference is the first
 
4715
    element in the list of children because the children are inserted
 
4716
    in reverse order.
 
4717
 
 
4718
  RETURN
 
4719
    - If 'this' is a nested table reference - the right-most child of
 
4720
      the tree rooted in 'this',
 
4721
    - else - 'this'
 
4722
*/
 
4723
 
 
4724
TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution()
 
4725
{
 
4726
  TABLE_LIST *cur_table_ref= this;
 
4727
  NESTED_JOIN *cur_nested_join;
 
4728
 
 
4729
  if (is_leaf_for_name_resolution())
 
4730
    return this;
 
4731
  DBUG_ASSERT(nested_join);
 
4732
 
 
4733
  for (cur_nested_join= nested_join;
 
4734
       cur_nested_join;
 
4735
       cur_nested_join= cur_table_ref->nested_join)
 
4736
  {
 
4737
    cur_table_ref= cur_nested_join->join_list.head();
 
4738
    /*
 
4739
      If the current nested is a RIGHT JOIN, the operands in
 
4740
      'join_list' are in reverse order, thus the last operand is in the
 
4741
      end of the list.
 
4742
    */
 
4743
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
4744
    {
 
4745
      List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
 
4746
      TABLE_LIST *next;
 
4747
      cur_table_ref= it++;
 
4748
      while ((next= it++))
 
4749
        cur_table_ref= next;
 
4750
    }
 
4751
    if (cur_table_ref->is_leaf_for_name_resolution())
 
4752
      break;
 
4753
  }
 
4754
  return cur_table_ref;
 
4755
}
 
4756
 
 
4757
 
 
4758
/*
 
4759
  Register access mode which we need for underlying tables
 
4760
 
 
4761
  SYNOPSIS
 
4762
    register_want_access()
 
4763
    want_access          Acess which we require
 
4764
*/
 
4765
 
 
4766
void TABLE_LIST::register_want_access(ulong want_access)
 
4767
{
 
4768
  /* Remove SHOW_VIEW_ACL, because it will be checked during making view */
 
4769
  want_access&= ~SHOW_VIEW_ACL;
 
4770
  if (belong_to_view)
 
4771
  {
 
4772
    grant.want_privilege= want_access;
 
4773
    if (table)
 
4774
      table->grant.want_privilege= want_access;
 
4775
  }
 
4776
  if (!view)
 
4777
    return;
 
4778
  for (TABLE_LIST *tbl= view->select_lex.get_table_list();
 
4779
       tbl;
 
4780
       tbl= tbl->next_local)
 
4781
    tbl->register_want_access(want_access);
 
4782
}
 
4783
 
 
4784
 
 
4785
/*
 
4786
  Load security context information for this view
 
4787
 
 
4788
  SYNOPSIS
 
4789
    TABLE_LIST::prepare_view_securety_context()
 
4790
    thd                  [in] thread handler
 
4791
 
 
4792
  RETURN
 
4793
    FALSE  OK
 
4794
    TRUE   Error
 
4795
*/
 
4796
 
 
4797
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
4798
bool TABLE_LIST::prepare_view_securety_context(THD *thd)
 
4799
{
 
4800
  DBUG_ENTER("TABLE_LIST::prepare_view_securety_context");
 
4801
  DBUG_PRINT("enter", ("table: %s", alias));
 
4802
 
 
4803
  DBUG_ASSERT(!prelocking_placeholder && view);
 
4804
  if (view_suid)
 
4805
  {
 
4806
    DBUG_PRINT("info", ("This table is suid view => load contest"));
 
4807
    DBUG_ASSERT(view && view_sctx);
 
4808
    if (acl_getroot(view_sctx, definer.user.str, definer.host.str,
 
4809
                                definer.host.str, thd->db))
 
4810
    {
 
4811
      if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) ||
 
4812
          (thd->lex->sql_command == SQLCOM_SHOW_FIELDS))
 
4813
      {
 
4814
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 
 
4815
                            ER_NO_SUCH_USER, 
 
4816
                            ER(ER_NO_SUCH_USER),
 
4817
                            definer.user.str, definer.host.str);
 
4818
      }
 
4819
      else
 
4820
      {
 
4821
        if (thd->security_ctx->master_access & SUPER_ACL)
 
4822
        {
 
4823
          my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str);
 
4824
 
 
4825
        }
 
4826
        else
 
4827
        {
 
4828
          if (thd->password == 2)
 
4829
            my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
 
4830
                     thd->security_ctx->priv_user,
 
4831
                     thd->security_ctx->priv_host);
 
4832
          else
 
4833
            my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
 
4834
                     thd->security_ctx->priv_user,
 
4835
                     thd->security_ctx->priv_host,
 
4836
                     (thd->password ?  ER(ER_YES) : ER(ER_NO)));
 
4837
        }
 
4838
        DBUG_RETURN(TRUE);
 
4839
      }
 
4840
    }
 
4841
  }
 
4842
  DBUG_RETURN(FALSE);
 
4843
}
 
4844
#endif
 
4845
 
 
4846
 
 
4847
/*
 
4848
  Find security context of current view
 
4849
 
 
4850
  SYNOPSIS
 
4851
    TABLE_LIST::find_view_security_context()
 
4852
    thd                  [in] thread handler
 
4853
 
 
4854
*/
 
4855
 
 
4856
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
4857
Security_context *TABLE_LIST::find_view_security_context(THD *thd)
 
4858
{
 
4859
  Security_context *sctx;
 
4860
  TABLE_LIST *upper_view= this;
 
4861
  DBUG_ENTER("TABLE_LIST::find_view_security_context");
 
4862
 
 
4863
  DBUG_ASSERT(view);
 
4864
  while (upper_view && !upper_view->view_suid)
 
4865
  {
 
4866
    DBUG_ASSERT(!upper_view->prelocking_placeholder);
 
4867
    upper_view= upper_view->referencing_view;
 
4868
  }
 
4869
  if (upper_view)
 
4870
  {
 
4871
    DBUG_PRINT("info", ("Securety context of view %s will be used",
 
4872
                        upper_view->alias));
 
4873
    sctx= upper_view->view_sctx;
 
4874
    DBUG_ASSERT(sctx);
 
4875
  }
 
4876
  else
 
4877
  {
 
4878
    DBUG_PRINT("info", ("Current global context will be used"));
 
4879
    sctx= thd->security_ctx;
 
4880
  }
 
4881
  DBUG_RETURN(sctx);
 
4882
}
 
4883
#endif
 
4884
 
 
4885
 
 
4886
/*
 
4887
  Prepare security context and load underlying tables priveleges for view
 
4888
 
 
4889
  SYNOPSIS
 
4890
    TABLE_LIST::prepare_security()
 
4891
    thd                  [in] thread handler
 
4892
 
 
4893
  RETURN
 
4894
    FALSE  OK
 
4895
    TRUE   Error
 
4896
*/
 
4897
 
 
4898
bool TABLE_LIST::prepare_security(THD *thd)
 
4899
{
 
4900
  List_iterator_fast<TABLE_LIST> tb(*view_tables);
 
4901
  TABLE_LIST *tbl;
 
4902
  DBUG_ENTER("TABLE_LIST::prepare_security");
 
4903
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
4904
  Security_context *save_security_ctx= thd->security_ctx;
 
4905
 
 
4906
  DBUG_ASSERT(!prelocking_placeholder);
 
4907
  if (prepare_view_securety_context(thd))
 
4908
    DBUG_RETURN(TRUE);
 
4909
  thd->security_ctx= find_view_security_context(thd);
 
4910
  while ((tbl= tb++))
 
4911
  {
 
4912
    DBUG_ASSERT(tbl->referencing_view);
 
4913
    char *local_db, *local_table_name;
 
4914
    if (tbl->view)
 
4915
    {
 
4916
      local_db= tbl->view_db.str;
 
4917
      local_table_name= tbl->view_name.str;
 
4918
    }
 
4919
    else
 
4920
    {
 
4921
      local_db= tbl->db;
 
4922
      local_table_name= tbl->table_name;
 
4923
    }
 
4924
    fill_effective_table_privileges(thd, &tbl->grant, local_db,
 
4925
                                    local_table_name);
 
4926
    if (tbl->table)
 
4927
      tbl->table->grant= grant;
 
4928
  }
 
4929
  thd->security_ctx= save_security_ctx;
 
4930
#else
 
4931
  while ((tbl= tb++))
 
4932
    tbl->grant.privilege= ~NO_ACCESS;
 
4933
#endif
 
4934
  DBUG_RETURN(FALSE);
 
4935
}
 
4936
 
 
4937
#ifndef DBUG_OFF
 
4938
void TABLE_LIST::set_check_merged()
 
4939
{
 
4940
  DBUG_ASSERT(derived);
 
4941
  /*
 
4942
    It is not simple to check all, but at least this should be checked:
 
4943
    this select is not excluded or the exclusion came from above.
 
4944
  */
 
4945
  DBUG_ASSERT(!derived->first_select()->exclude_from_table_unique_test ||
 
4946
              derived->outer_select()->
 
4947
              exclude_from_table_unique_test);
 
4948
}
 
4949
#endif
 
4950
 
 
4951
void TABLE_LIST::set_check_materialized()
 
4952
{
 
4953
  DBUG_ASSERT(derived);
 
4954
  if (!derived->first_select()->exclude_from_table_unique_test)
 
4955
    derived->set_unique_exclude();
 
4956
  else
 
4957
  {
 
4958
    /*
 
4959
      The subtree should be already excluded
 
4960
    */
 
4961
    DBUG_ASSERT(!derived->first_select()->first_inner_unit() ||
 
4962
                derived->first_select()->first_inner_unit()->first_select()->
 
4963
                exclude_from_table_unique_test);
 
4964
  }
 
4965
}
 
4966
 
 
4967
TABLE *TABLE_LIST::get_real_join_table()
 
4968
{
 
4969
  TABLE_LIST *tbl= this;
 
4970
  while (tbl->table == NULL || tbl->table->reginfo.join_tab == NULL)
 
4971
  {
 
4972
    if (tbl->view == NULL && tbl->derived == NULL)
 
4973
      break;
 
4974
    /* we do not support merging of union yet */
 
4975
    DBUG_ASSERT(tbl->view == NULL ||
 
4976
               tbl->view->select_lex.next_select() == NULL);
 
4977
    DBUG_ASSERT(tbl->derived == NULL ||
 
4978
               tbl->derived->first_select()->next_select() == NULL);
 
4979
 
 
4980
    {
 
4981
      List_iterator_fast<TABLE_LIST> ti;
 
4982
      {
 
4983
        List_iterator_fast<TABLE_LIST>
 
4984
          ti(tbl->view != NULL ?
 
4985
             tbl->view->select_lex.top_join_list :
 
4986
             tbl->derived->first_select()->top_join_list);
 
4987
        for (;;)
 
4988
        {
 
4989
          tbl= NULL;
 
4990
          /*
 
4991
            Find left table in outer join on this level
 
4992
            (the list is reverted).
 
4993
          */
 
4994
          for (TABLE_LIST *t= ti++; t; t= ti++)
 
4995
            tbl= t;
 
4996
          /*
 
4997
            It is impossible that the list is empty
 
4998
            so tbl can't be NULL after above loop.
 
4999
          */
 
5000
          if (!tbl->nested_join)
 
5001
            break;
 
5002
          /* go deeper if we've found nested join */
 
5003
          ti= tbl->nested_join->join_list;
 
5004
        }
 
5005
      }
 
5006
    }
 
5007
  }
 
5008
 
 
5009
  return tbl->table;
 
5010
}
 
5011
 
 
5012
 
 
5013
Natural_join_column::Natural_join_column(Field_translator *field_param,
 
5014
                                         TABLE_LIST *tab)
 
5015
{
 
5016
  DBUG_ASSERT(tab->field_translation);
 
5017
  view_field= field_param;
 
5018
  table_field= NULL;
 
5019
  table_ref= tab;
 
5020
  is_common= FALSE;
 
5021
}
 
5022
 
 
5023
 
 
5024
Natural_join_column::Natural_join_column(Item_field *field_param,
 
5025
                                         TABLE_LIST *tab)
 
5026
{
 
5027
  DBUG_ASSERT(tab->table == field_param->field->table);
 
5028
  table_field= field_param;
 
5029
  view_field= NULL;
 
5030
  table_ref= tab;
 
5031
  is_common= FALSE;
 
5032
}
 
5033
 
 
5034
 
 
5035
const char *Natural_join_column::name()
 
5036
{
 
5037
  if (view_field)
 
5038
  {
 
5039
    DBUG_ASSERT(table_field == NULL);
 
5040
    return view_field->name;
 
5041
  }
 
5042
 
 
5043
  return table_field->field_name;
 
5044
}
 
5045
 
 
5046
 
 
5047
Item *Natural_join_column::create_item(THD *thd)
 
5048
{
 
5049
  if (view_field)
 
5050
  {
 
5051
    DBUG_ASSERT(table_field == NULL);
 
5052
    return create_view_field(thd, table_ref, &view_field->item,
 
5053
                             view_field->name);
 
5054
  }
 
5055
  return table_field;
 
5056
}
 
5057
 
 
5058
 
 
5059
Field *Natural_join_column::field()
 
5060
{
 
5061
  if (view_field)
 
5062
  {
 
5063
    DBUG_ASSERT(table_field == NULL);
 
5064
    return NULL;
 
5065
  }
 
5066
  return table_field->field;
 
5067
}
 
5068
 
 
5069
 
 
5070
const char *Natural_join_column::table_name()
 
5071
{
 
5072
  DBUG_ASSERT(table_ref);
 
5073
  return table_ref->alias;
 
5074
}
 
5075
 
 
5076
 
 
5077
const char *Natural_join_column::db_name()
 
5078
{
 
5079
  if (view_field)
 
5080
    return table_ref->view_db.str;
 
5081
 
 
5082
  /*
 
5083
    Test that TABLE_LIST::db is the same as TABLE_SHARE::db to
 
5084
    ensure consistency. An exception are I_S schema tables, which
 
5085
    are inconsistent in this respect.
 
5086
  */
 
5087
  DBUG_ASSERT(!strcmp(table_ref->db,
 
5088
                      table_ref->table->s->db.str) ||
 
5089
              (table_ref->schema_table &&
 
5090
               is_infoschema_db(table_ref->table->s->db.str,
 
5091
                                table_ref->table->s->db.length)) ||
 
5092
               table_ref->is_materialized_derived());
 
5093
  return table_ref->db;
 
5094
}
 
5095
 
 
5096
 
 
5097
GRANT_INFO *Natural_join_column::grant()
 
5098
{
 
5099
/*  if (view_field)
 
5100
    return &(table_ref->grant);
 
5101
  return &(table_ref->table->grant);*/
 
5102
  /*
 
5103
    Have to check algorithm because merged derived also has
 
5104
    field_translation.
 
5105
  */
 
5106
//if (table_ref->effective_algorithm == DTYPE_ALGORITHM_MERGE)
 
5107
  if (table_ref->is_merged_derived())
 
5108
    return &(table_ref->grant);
 
5109
  return &(table_ref->table->grant);
 
5110
}
 
5111
 
 
5112
 
 
5113
void Field_iterator_view::set(TABLE_LIST *table)
 
5114
{
 
5115
  DBUG_ASSERT(table->field_translation);
 
5116
  view= table;
 
5117
  ptr= table->field_translation;
 
5118
  array_end= table->field_translation_end;
 
5119
}
 
5120
 
 
5121
 
 
5122
const char *Field_iterator_table::name()
 
5123
{
 
5124
  return (*ptr)->field_name;
 
5125
}
 
5126
 
 
5127
 
 
5128
Item *Field_iterator_table::create_item(THD *thd)
 
5129
{
 
5130
  SELECT_LEX *select= thd->lex->current_select;
 
5131
 
 
5132
  Item_field *item= new Item_field(thd, &select->context, *ptr);
 
5133
  if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
 
5134
      !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
 
5135
  {
 
5136
    select->non_agg_fields.push_back(item);
 
5137
    item->marker= select->cur_pos_in_select_list;
 
5138
    select->set_non_agg_field_used(true);
 
5139
  }
 
5140
  return item;
 
5141
}
 
5142
 
 
5143
 
 
5144
const char *Field_iterator_view::name()
 
5145
{
 
5146
  return ptr->name;
 
5147
}
 
5148
 
 
5149
 
 
5150
Item *Field_iterator_view::create_item(THD *thd)
 
5151
{
 
5152
  return create_view_field(thd, view, &ptr->item, ptr->name);
 
5153
}
 
5154
 
 
5155
Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
 
5156
                        const char *name)
 
5157
{
 
5158
  bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
 
5159
  Item *field= *field_ref;
 
5160
  DBUG_ENTER("create_view_field");
 
5161
 
 
5162
  if (view->schema_table_reformed)
 
5163
  {
 
5164
    /*
 
5165
      Translation table items are always Item_fields and already fixed
 
5166
      ('mysql_schema_table' function). So we can return directly the
 
5167
      field. This case happens only for 'show & where' commands.
 
5168
    */
 
5169
    DBUG_ASSERT(field && field->fixed);
 
5170
    DBUG_RETURN(field);
 
5171
  }
 
5172
 
 
5173
  DBUG_ASSERT(field);
 
5174
  thd->lex->current_select->no_wrap_view_item= TRUE;
 
5175
  if (!field->fixed)
 
5176
  {
 
5177
    if (field->fix_fields(thd, field_ref))
 
5178
    {
 
5179
      thd->lex->current_select->no_wrap_view_item= save_wrapper;
 
5180
      DBUG_RETURN(0);
 
5181
    }
 
5182
    field= *field_ref;
 
5183
  }
 
5184
  thd->lex->current_select->no_wrap_view_item= save_wrapper;
 
5185
  if (save_wrapper)
 
5186
  {
 
5187
    DBUG_RETURN(field);
 
5188
  }
 
5189
  Item *item= new Item_direct_view_ref(&view->view->select_lex.context,
 
5190
                                       field_ref, view->alias,
 
5191
                                       name, view);
 
5192
  /*
 
5193
    Force creation of nullable item for the result tmp table for outer joined
 
5194
    views/derived tables.
 
5195
  */
 
5196
  if (view->table && view->table->maybe_null)
 
5197
    item->maybe_null= TRUE;
 
5198
  /* Save item in case we will need to fall back to materialization. */
 
5199
  view->used_items.push_front(item);
 
5200
  DBUG_RETURN(item);
 
5201
}
 
5202
 
 
5203
 
 
5204
void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
 
5205
{
 
5206
  DBUG_ASSERT(table_ref->join_columns);
 
5207
  column_ref_it.init(*(table_ref->join_columns));
 
5208
  cur_column_ref= column_ref_it++;
 
5209
}
 
5210
 
 
5211
 
 
5212
void Field_iterator_natural_join::next()
 
5213
{
 
5214
  cur_column_ref= column_ref_it++;
 
5215
  DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
 
5216
              cur_column_ref->table_ref->table ==
 
5217
              cur_column_ref->table_field->field->table);
 
5218
}
 
5219
 
 
5220
 
 
5221
void Field_iterator_table_ref::set_field_iterator()
 
5222
{
 
5223
  DBUG_ENTER("Field_iterator_table_ref::set_field_iterator");
 
5224
  /*
 
5225
    If the table reference we are iterating over is a natural join, or it is
 
5226
    an operand of a natural join, and TABLE_LIST::join_columns contains all
 
5227
    the columns of the join operand, then we pick the columns from
 
5228
    TABLE_LIST::join_columns, instead of the  orginial container of the
 
5229
    columns of the join operator.
 
5230
  */
 
5231
  if (table_ref->is_join_columns_complete)
 
5232
  {
 
5233
    /* Necesary, but insufficient conditions. */
 
5234
    DBUG_ASSERT(table_ref->is_natural_join ||
 
5235
                table_ref->nested_join ||
 
5236
                (table_ref->join_columns &&
 
5237
                 /* This is a merge view. */
 
5238
                 ((table_ref->field_translation &&
 
5239
                   table_ref->join_columns->elements ==
 
5240
                   (ulong)(table_ref->field_translation_end -
 
5241
                           table_ref->field_translation)) ||
 
5242
                  /* This is stored table or a tmptable view. */
 
5243
                  (!table_ref->field_translation &&
 
5244
                   table_ref->join_columns->elements ==
 
5245
                   table_ref->table->s->fields))));
 
5246
    field_it= &natural_join_it;
 
5247
    DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join",
 
5248
                       table_ref->alias));
 
5249
  }
 
5250
  /* This is a merge view, so use field_translation. */
 
5251
  else if (table_ref->field_translation)
 
5252
  {
 
5253
    DBUG_ASSERT(table_ref->is_merged_derived());
 
5254
    field_it= &view_field_it;
 
5255
    DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
 
5256
                        table_ref->alias));
 
5257
  }
 
5258
  /* This is a base table or stored view. */
 
5259
  else
 
5260
  {
 
5261
    DBUG_ASSERT(table_ref->table || table_ref->view);
 
5262
    field_it= &table_field_it;
 
5263
    DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_table",
 
5264
                        table_ref->alias));
 
5265
  }
 
5266
  field_it->set(table_ref);
 
5267
  DBUG_VOID_RETURN;
 
5268
}
 
5269
 
 
5270
 
 
5271
void Field_iterator_table_ref::set(TABLE_LIST *table)
 
5272
{
 
5273
  DBUG_ASSERT(table);
 
5274
  first_leaf= table->first_leaf_for_name_resolution();
 
5275
  last_leaf=  table->last_leaf_for_name_resolution();
 
5276
  DBUG_ASSERT(first_leaf && last_leaf);
 
5277
  table_ref= first_leaf;
 
5278
  set_field_iterator();
 
5279
}
 
5280
 
 
5281
 
 
5282
void Field_iterator_table_ref::next()
 
5283
{
 
5284
  /* Move to the next field in the current table reference. */
 
5285
  field_it->next();
 
5286
  /*
 
5287
    If all fields of the current table reference are exhausted, move to
 
5288
    the next leaf table reference.
 
5289
  */
 
5290
  if (field_it->end_of_fields() && table_ref != last_leaf)
 
5291
  {
 
5292
    table_ref= table_ref->next_name_resolution_table;
 
5293
    DBUG_ASSERT(table_ref);
 
5294
    set_field_iterator();
 
5295
  }
 
5296
}
 
5297
 
 
5298
 
 
5299
const char *Field_iterator_table_ref::get_table_name()
 
5300
{
 
5301
  if (table_ref->view)
 
5302
    return table_ref->view_name.str;
 
5303
  else if (table_ref->is_natural_join)
 
5304
    return natural_join_it.column_ref()->table_name();
 
5305
 
 
5306
  DBUG_ASSERT(!strcmp(table_ref->table_name,
 
5307
                      table_ref->table->s->table_name.str));
 
5308
  return table_ref->table_name;
 
5309
}
 
5310
 
 
5311
 
 
5312
const char *Field_iterator_table_ref::get_db_name()
 
5313
{
 
5314
  if (table_ref->view)
 
5315
    return table_ref->view_db.str;
 
5316
  else if (table_ref->is_natural_join)
 
5317
    return natural_join_it.column_ref()->db_name();
 
5318
 
 
5319
  /*
 
5320
    Test that TABLE_LIST::db is the same as TABLE_SHARE::db to
 
5321
    ensure consistency. An exception are I_S schema tables, which
 
5322
    are inconsistent in this respect.
 
5323
  */
 
5324
  DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
 
5325
              (table_ref->schema_table &&
 
5326
               is_infoschema_db(table_ref->table->s->db.str,
 
5327
                                table_ref->table->s->db.length)));
 
5328
 
 
5329
  return table_ref->db;
 
5330
}
 
5331
 
 
5332
 
 
5333
GRANT_INFO *Field_iterator_table_ref::grant()
 
5334
{
 
5335
  if (table_ref->view)
 
5336
    return &(table_ref->grant);
 
5337
  else if (table_ref->is_natural_join)
 
5338
    return natural_join_it.column_ref()->grant();
 
5339
  return &(table_ref->table->grant);
 
5340
}
 
5341
 
 
5342
 
 
5343
/*
 
5344
  Create new or return existing column reference to a column of a
 
5345
  natural/using join.
 
5346
 
 
5347
  SYNOPSIS
 
5348
    Field_iterator_table_ref::get_or_create_column_ref()
 
5349
    parent_table_ref  the parent table reference over which the
 
5350
                      iterator is iterating
 
5351
 
 
5352
  DESCRIPTION
 
5353
    Create a new natural join column for the current field of the
 
5354
    iterator if no such column was created, or return an already
 
5355
    created natural join column. The former happens for base tables or
 
5356
    views, and the latter for natural/using joins. If a new field is
 
5357
    created, then the field is added to 'parent_table_ref' if it is
 
5358
    given, or to the original table referene of the field if
 
5359
    parent_table_ref == NULL.
 
5360
 
 
5361
  NOTES
 
5362
    This method is designed so that when a Field_iterator_table_ref
 
5363
    walks through the fields of a table reference, all its fields
 
5364
    are created and stored as follows:
 
5365
    - If the table reference being iterated is a stored table, view or
 
5366
      natural/using join, store all natural join columns in a list
 
5367
      attached to that table reference.
 
5368
    - If the table reference being iterated is a nested join that is
 
5369
      not natural/using join, then do not materialize its result
 
5370
      fields. This is OK because for such table references
 
5371
      Field_iterator_table_ref iterates over the fields of the nested
 
5372
      table references (recursively). In this way we avoid the storage
 
5373
      of unnecessay copies of result columns of nested joins.
 
5374
 
 
5375
  RETURN
 
5376
    #     Pointer to a column of a natural join (or its operand)
 
5377
    NULL  No memory to allocate the column
 
5378
*/
 
5379
 
 
5380
Natural_join_column *
 
5381
Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_table_ref)
 
5382
{
 
5383
  Natural_join_column *nj_col;
 
5384
  bool is_created= TRUE;
 
5385
  uint field_count;
 
5386
  TABLE_LIST *add_table_ref= parent_table_ref ?
 
5387
                             parent_table_ref : table_ref;
 
5388
  LINT_INIT(field_count);
 
5389
 
 
5390
  if (field_it == &table_field_it)
 
5391
  {
 
5392
    /* The field belongs to a stored table. */
 
5393
    Field *tmp_field= table_field_it.field();
 
5394
    Item_field *tmp_item=
 
5395
      new Item_field(thd, &thd->lex->current_select->context, tmp_field);
 
5396
    if (!tmp_item)
 
5397
      return NULL;
 
5398
    nj_col= new Natural_join_column(tmp_item, table_ref);
 
5399
    field_count= table_ref->table->s->fields;
 
5400
  }
 
5401
  else if (field_it == &view_field_it)
 
5402
  {
 
5403
    /* The field belongs to a merge view or information schema table. */
 
5404
    Field_translator *translated_field= view_field_it.field_translator();
 
5405
    nj_col= new Natural_join_column(translated_field, table_ref);
 
5406
    field_count= table_ref->field_translation_end -
 
5407
                 table_ref->field_translation;
 
5408
  }
 
5409
  else
 
5410
  {
 
5411
    /*
 
5412
      The field belongs to a NATURAL join, therefore the column reference was
 
5413
      already created via one of the two constructor calls above. In this case
 
5414
      we just return the already created column reference.
 
5415
    */
 
5416
    DBUG_ASSERT(table_ref->is_join_columns_complete);
 
5417
    is_created= FALSE;
 
5418
    nj_col= natural_join_it.column_ref();
 
5419
    DBUG_ASSERT(nj_col);
 
5420
  }
 
5421
  DBUG_ASSERT(!nj_col->table_field ||
 
5422
              nj_col->table_ref->table == nj_col->table_field->field->table);
 
5423
 
 
5424
  /*
 
5425
    If the natural join column was just created add it to the list of
 
5426
    natural join columns of either 'parent_table_ref' or to the table
 
5427
    reference that directly contains the original field.
 
5428
  */
 
5429
  if (is_created)
 
5430
  {
 
5431
    /* Make sure not all columns were materialized. */
 
5432
    DBUG_ASSERT(!add_table_ref->is_join_columns_complete);
 
5433
    if (!add_table_ref->join_columns)
 
5434
    {
 
5435
      /* Create a list of natural join columns on demand. */
 
5436
      if (!(add_table_ref->join_columns= new List<Natural_join_column>))
 
5437
        return NULL;
 
5438
      add_table_ref->is_join_columns_complete= FALSE;
 
5439
    }
 
5440
    add_table_ref->join_columns->push_back(nj_col);
 
5441
    /*
 
5442
      If new fields are added to their original table reference, mark if
 
5443
      all fields were added. We do it here as the caller has no easy way
 
5444
      of knowing when to do it.
 
5445
      If the fields are being added to parent_table_ref, then the caller
 
5446
      must take care to mark when all fields are created/added.
 
5447
    */
 
5448
    if (!parent_table_ref &&
 
5449
        add_table_ref->join_columns->elements == field_count)
 
5450
      add_table_ref->is_join_columns_complete= TRUE;
 
5451
  }
 
5452
 
 
5453
  return nj_col;
 
5454
}
 
5455
 
 
5456
 
 
5457
/*
 
5458
  Return an existing reference to a column of a natural/using join.
 
5459
 
 
5460
  SYNOPSIS
 
5461
    Field_iterator_table_ref::get_natural_column_ref()
 
5462
 
 
5463
  DESCRIPTION
 
5464
    The method should be called in contexts where it is expected that
 
5465
    all natural join columns are already created, and that the column
 
5466
    being retrieved is a Natural_join_column.
 
5467
 
 
5468
  RETURN
 
5469
    #     Pointer to a column of a natural join (or its operand)
 
5470
    NULL  No memory to allocate the column
 
5471
*/
 
5472
 
 
5473
Natural_join_column *
 
5474
Field_iterator_table_ref::get_natural_column_ref()
 
5475
{
 
5476
  Natural_join_column *nj_col;
 
5477
 
 
5478
  DBUG_ASSERT(field_it == &natural_join_it);
 
5479
  /*
 
5480
    The field belongs to a NATURAL join, therefore the column reference was
 
5481
    already created via one of the two constructor calls above. In this case
 
5482
    we just return the already created column reference.
 
5483
  */
 
5484
  nj_col= natural_join_it.column_ref();
 
5485
  DBUG_ASSERT(nj_col &&
 
5486
              (!nj_col->table_field ||
 
5487
               nj_col->table_ref->table == nj_col->table_field->field->table));
 
5488
  return nj_col;
 
5489
}
 
5490
 
 
5491
/*****************************************************************************
 
5492
  Functions to handle column usage bitmaps (read_set, write_set etc...)
 
5493
*****************************************************************************/
 
5494
 
 
5495
/* Reset all columns bitmaps */
 
5496
 
 
5497
void TABLE::clear_column_bitmaps()
 
5498
{
 
5499
  /*
 
5500
    Reset column read/write usage. It's identical to:
 
5501
    bitmap_clear_all(&table->def_read_set);
 
5502
    bitmap_clear_all(&table->def_write_set);
 
5503
    bitmap_clear_all(&table->def_vcol_set);
 
5504
  */
 
5505
  bzero((char*) def_read_set.bitmap, s->column_bitmap_size*3);
 
5506
  column_bitmaps_set(&def_read_set, &def_write_set, &def_vcol_set);
 
5507
}
 
5508
 
 
5509
 
 
5510
/*
 
5511
  Tell handler we are going to call position() and rnd_pos() later.
 
5512
  
 
5513
  NOTES:
 
5514
  This is needed for handlers that uses the primary key to find the
 
5515
  row. In this case we have to extend the read bitmap with the primary
 
5516
  key fields.
 
5517
*/
 
5518
 
 
5519
void TABLE::prepare_for_position()
 
5520
{
 
5521
  DBUG_ENTER("TABLE::prepare_for_position");
 
5522
 
 
5523
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
5524
      s->primary_key < MAX_KEY)
 
5525
  {
 
5526
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
5527
    /* signal change */
 
5528
    file->column_bitmaps_signal();
 
5529
  }
 
5530
  DBUG_VOID_RETURN;
 
5531
}
 
5532
 
 
5533
 
 
5534
/*
 
5535
  Mark that only fields from one key is used
 
5536
 
 
5537
  NOTE:
 
5538
    This changes the bitmap to use the tmp bitmap
 
5539
    After this, you can't access any other columns in the table until
 
5540
    bitmaps are reset, for example with TABLE::clear_column_bitmaps()
 
5541
    or TABLE::restore_column_maps_after_mark_index()
 
5542
*/
 
5543
 
 
5544
void TABLE::mark_columns_used_by_index(uint index)
 
5545
{
 
5546
  MY_BITMAP *bitmap= &tmp_set;
 
5547
  DBUG_ENTER("TABLE::mark_columns_used_by_index");
 
5548
 
 
5549
  enable_keyread();
 
5550
  bitmap_clear_all(bitmap);
 
5551
  mark_columns_used_by_index_no_reset(index, bitmap);
 
5552
  column_bitmaps_set(bitmap, bitmap);
 
5553
  DBUG_VOID_RETURN;
 
5554
}
 
5555
 
 
5556
 
 
5557
/*
 
5558
  Add fields used by a specified index to the table's read_set.
 
5559
 
 
5560
  NOTE:
 
5561
    The original state can be restored with
 
5562
    restore_column_maps_after_mark_index().
 
5563
*/
 
5564
 
 
5565
void TABLE::add_read_columns_used_by_index(uint index)
 
5566
{
 
5567
  MY_BITMAP *bitmap= &tmp_set;
 
5568
  DBUG_ENTER("TABLE::add_read_columns_used_by_index");
 
5569
 
 
5570
  enable_keyread();
 
5571
  bitmap_copy(bitmap, read_set);
 
5572
  mark_columns_used_by_index_no_reset(index, bitmap);
 
5573
  column_bitmaps_set(bitmap, write_set);
 
5574
  DBUG_VOID_RETURN;
 
5575
}
 
5576
 
 
5577
 
 
5578
/*
 
5579
  Restore to use normal column maps after key read
 
5580
 
 
5581
  NOTES
 
5582
    This reverse the change done by mark_columns_used_by_index
 
5583
 
 
5584
  WARNING
 
5585
    For this to work, one must have the normal table maps in place
 
5586
    when calling mark_columns_used_by_index
 
5587
*/
 
5588
 
 
5589
void TABLE::restore_column_maps_after_mark_index()
 
5590
{
 
5591
  DBUG_ENTER("TABLE::restore_column_maps_after_mark_index");
 
5592
 
 
5593
  disable_keyread();
 
5594
  default_column_bitmaps();
 
5595
  file->column_bitmaps_signal();
 
5596
  DBUG_VOID_RETURN;
 
5597
}
 
5598
 
 
5599
 
 
5600
/*
 
5601
  mark columns used by key, but don't reset other fields
 
5602
*/
 
5603
 
 
5604
void TABLE::mark_columns_used_by_index_no_reset(uint index,
 
5605
                                                   MY_BITMAP *bitmap)
 
5606
{
 
5607
  KEY_PART_INFO *key_part= key_info[index].key_part;
 
5608
  KEY_PART_INFO *key_part_end= (key_part +
 
5609
                                key_info[index].key_parts);
 
5610
  for (;key_part != key_part_end; key_part++)
 
5611
  {
 
5612
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
5613
    if (key_part->field->vcol_info &&
 
5614
        key_part->field->vcol_info->expr_item)
 
5615
      key_part->field->vcol_info->
 
5616
               expr_item->walk(&Item::register_field_in_bitmap, 
 
5617
                               1, (uchar *) bitmap);
 
5618
  }
 
5619
}
 
5620
 
 
5621
 
 
5622
/*
 
5623
  Mark auto-increment fields as used fields in both read and write maps
 
5624
 
 
5625
  NOTES
 
5626
    This is needed in insert & update as the auto-increment field is
 
5627
    always set and sometimes read.
 
5628
*/
 
5629
 
 
5630
void TABLE::mark_auto_increment_column()
 
5631
{
 
5632
  DBUG_ASSERT(found_next_number_field);
 
5633
  /*
 
5634
    We must set bit in read set as update_auto_increment() is using the
 
5635
    store() to check overflow of auto_increment values
 
5636
  */
 
5637
  bitmap_set_bit(read_set, found_next_number_field->field_index);
 
5638
  bitmap_set_bit(write_set, found_next_number_field->field_index);
 
5639
  if (s->next_number_keypart)
 
5640
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
 
5641
  file->column_bitmaps_signal();
 
5642
}
 
5643
 
 
5644
 
 
5645
/*
 
5646
  Mark columns needed for doing an delete of a row
 
5647
 
 
5648
  DESCRIPTON
 
5649
    Some table engines don't have a cursor on the retrieve rows
 
5650
    so they need either to use the primary key or all columns to
 
5651
    be able to delete a row.
 
5652
 
 
5653
    If the engine needs this, the function works as follows:
 
5654
    - If primary key exits, mark the primary key columns to be read.
 
5655
    - If not, mark all columns to be read
 
5656
 
 
5657
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
5658
    mark all key columns as 'to-be-read'. This allows the engine to
 
5659
    loop over the given record to find all keys and doesn't have to
 
5660
    retrieve the row again.
 
5661
*/
 
5662
 
 
5663
void TABLE::mark_columns_needed_for_delete()
 
5664
{
 
5665
  if (triggers)
 
5666
    triggers->mark_fields_used(TRG_EVENT_DELETE);
 
5667
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
 
5668
  {
 
5669
    Field **reg_field;
 
5670
    for (reg_field= field ; *reg_field ; reg_field++)
 
5671
    {
 
5672
      if ((*reg_field)->flags & PART_KEY_FLAG)
 
5673
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
5674
    }
 
5675
    file->column_bitmaps_signal();
 
5676
  }
 
5677
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
 
5678
  {
 
5679
    /*
 
5680
      If the handler has no cursor capabilites, we have to read either
 
5681
      the primary key, the hidden primary key or all columns to be
 
5682
      able to do an delete
 
5683
    */
 
5684
    if (s->primary_key == MAX_KEY)
 
5685
      file->use_hidden_primary_key();
 
5686
    else
 
5687
    {
 
5688
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
5689
      file->column_bitmaps_signal();
 
5690
    }
 
5691
  }
 
5692
}
 
5693
 
 
5694
 
 
5695
/*
 
5696
  Mark columns needed for doing an update of a row
 
5697
 
 
5698
  DESCRIPTON
 
5699
    Some engines needs to have all columns in an update (to be able to
 
5700
    build a complete row). If this is the case, we mark all not
 
5701
    updated columns to be read.
 
5702
 
 
5703
    If this is no the case, we do like in the delete case and mark
 
5704
    if neeed, either the primary key column or all columns to be read.
 
5705
    (see mark_columns_needed_for_delete() for details)
 
5706
 
 
5707
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
5708
    mark all USED key columns as 'to-be-read'. This allows the engine to
 
5709
    loop over the given record to find all changed keys and doesn't have to
 
5710
    retrieve the row again.
 
5711
*/
 
5712
 
 
5713
void TABLE::mark_columns_needed_for_update()
 
5714
{
 
5715
  DBUG_ENTER("mark_columns_needed_for_update");
 
5716
  if (triggers)
 
5717
    triggers->mark_fields_used(TRG_EVENT_UPDATE);
 
5718
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
 
5719
  {
 
5720
    /* Mark all used key columns for read */
 
5721
    Field **reg_field;
 
5722
    for (reg_field= field ; *reg_field ; reg_field++)
 
5723
    {
 
5724
      /* Merge keys is all keys that had a column refered to in the query */
 
5725
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
 
5726
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
5727
    }
 
5728
    file->column_bitmaps_signal();
 
5729
  }
 
5730
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
 
5731
  {
 
5732
    /*
 
5733
      If the handler has no cursor capabilites, we have to read either
 
5734
      the primary key, the hidden primary key or all columns to be
 
5735
      able to do an update
 
5736
    */
 
5737
    if (s->primary_key == MAX_KEY)
 
5738
      file->use_hidden_primary_key();
 
5739
    else
 
5740
    {
 
5741
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
5742
      file->column_bitmaps_signal();
 
5743
    }
 
5744
  }
 
5745
  /* Mark all virtual columns needed for update */
 
5746
  mark_virtual_columns_for_write(FALSE);
 
5747
  DBUG_VOID_RETURN;
 
5748
}
 
5749
 
 
5750
 
 
5751
/*
 
5752
  Mark columns the handler needs for doing an insert
 
5753
 
 
5754
  For now, this is used to mark fields used by the trigger
 
5755
  as changed.
 
5756
*/
 
5757
 
 
5758
void TABLE::mark_columns_needed_for_insert()
 
5759
{
 
5760
  if (triggers)
 
5761
  {
 
5762
    /*
 
5763
      We don't need to mark columns which are used by ON DELETE and
 
5764
      ON UPDATE triggers, which may be invoked in case of REPLACE or
 
5765
      INSERT ... ON DUPLICATE KEY UPDATE, since before doing actual
 
5766
      row replacement or update write_record() will mark all table
 
5767
      fields as used.
 
5768
    */
 
5769
    triggers->mark_fields_used(TRG_EVENT_INSERT);
 
5770
  }
 
5771
  if (found_next_number_field)
 
5772
    mark_auto_increment_column();
 
5773
  /* Mark virtual columns for insert */
 
5774
  mark_virtual_columns_for_write(TRUE);
 
5775
}
 
5776
 
 
5777
 
 
5778
/*
 
5779
   @brief Mark a column as virtual used by the query
 
5780
 
 
5781
   @param field           the field for the column to be marked
 
5782
 
 
5783
   @details
 
5784
     The function marks the column for 'field' as virtual (computed)
 
5785
     in the bitmap vcol_set.
 
5786
     If the column is marked for the first time the expression to compute
 
5787
     the column is traversed and all columns that are occurred there are
 
5788
     marked in the read_set of the table.
 
5789
 
 
5790
   @retval
 
5791
     TRUE       if column is marked for the first time
 
5792
   @retval
 
5793
     FALSE      otherwise
 
5794
*/
 
5795
 
 
5796
bool TABLE::mark_virtual_col(Field *field)
 
5797
{
 
5798
  bool res;
 
5799
  DBUG_ASSERT(field->vcol_info);
 
5800
  if (!(res= bitmap_fast_test_and_set(vcol_set, field->field_index)))
 
5801
  {
 
5802
    Item *vcol_item= field->vcol_info->expr_item;
 
5803
    DBUG_ASSERT(vcol_item);
 
5804
    vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
 
5805
  }
 
5806
  return res;
 
5807
}
 
5808
 
 
5809
 
 
5810
/* 
 
5811
  @brief Mark virtual columns for update/insert commands
 
5812
    
 
5813
  @param insert_fl    <-> virtual columns are marked for insert command 
 
5814
 
 
5815
  @details
 
5816
    The function marks virtual columns used in a update/insert commands
 
5817
    in the vcol_set bitmap.
 
5818
    For an insert command a virtual column is always marked in write_set if
 
5819
    it is a stored column.
 
5820
    If a virtual column is from  write_set it is always marked in vcol_set.
 
5821
    If a stored virtual column is not from write_set but it is computed
 
5822
    through columns from write_set it is also marked in vcol_set, and,
 
5823
    besides, it is added to write_set. 
 
5824
 
 
5825
  @return       void
 
5826
 
 
5827
  @note
 
5828
    Let table t1 have columns a,b,c and let column c be a stored virtual 
 
5829
    column computed through columns a and b. Then for the query
 
5830
      UPDATE t1 SET a=1
 
5831
    column c will be placed into vcol_set and into write_set while
 
5832
    column b will be placed into read_set.
 
5833
    If column c was a virtual column, but not a stored virtual column
 
5834
    then it would not be added to any of the sets. Column b would not
 
5835
    be added to read_set either.           
 
5836
*/
 
5837
 
 
5838
void TABLE::mark_virtual_columns_for_write(bool insert_fl)
 
5839
{
 
5840
  Field **vfield_ptr, *tmp_vfield;
 
5841
  bool bitmap_updated= FALSE;
 
5842
 
 
5843
  if (!vfield)
 
5844
    return;
 
5845
 
 
5846
  if (!vfield)
 
5847
    return;
 
5848
 
 
5849
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
5850
  {
 
5851
    tmp_vfield= *vfield_ptr;
 
5852
    if (bitmap_is_set(write_set, tmp_vfield->field_index))
 
5853
      bitmap_updated= mark_virtual_col(tmp_vfield);
 
5854
    else if (tmp_vfield->stored_in_db)
 
5855
    {
 
5856
      bool mark_fl= insert_fl;
 
5857
      if (!mark_fl)
 
5858
      {
 
5859
        MY_BITMAP *save_read_set;
 
5860
        Item *vcol_item= tmp_vfield->vcol_info->expr_item;
 
5861
        DBUG_ASSERT(vcol_item);
 
5862
        bitmap_clear_all(&tmp_set);
 
5863
        save_read_set= read_set;
 
5864
        read_set= &tmp_set;
 
5865
        vcol_item->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
 
5866
        read_set= save_read_set;
 
5867
        bitmap_intersect(&tmp_set, write_set);
 
5868
        mark_fl= !bitmap_is_clear_all(&tmp_set);
 
5869
      }
 
5870
      if (mark_fl)
 
5871
      {
 
5872
        bitmap_set_bit(write_set, tmp_vfield->field_index);
 
5873
        mark_virtual_col(tmp_vfield);
 
5874
        bitmap_updated= TRUE;
 
5875
      }
 
5876
    } 
 
5877
  }
 
5878
  if (bitmap_updated)
 
5879
    file->column_bitmaps_signal();
 
5880
}
 
5881
 
 
5882
 
 
5883
/**
 
5884
  @brief
 
5885
  Allocate space for keys
 
5886
 
 
5887
  @param key_count  number of keys to allocate additionally
 
5888
 
 
5889
  @details
 
5890
  The function allocates memory  to fit additionally 'key_count' keys 
 
5891
  for this table.
 
5892
 
 
5893
  @return FALSE   space was successfully allocated
 
5894
  @return TRUE    an error occur
 
5895
*/
 
5896
 
 
5897
bool TABLE::alloc_keys(uint key_count)
 
5898
{
 
5899
  key_info= (KEY*) alloc_root(&mem_root, sizeof(KEY)*(s->keys+key_count));
 
5900
  if (s->keys)
 
5901
    memmove(key_info, s->key_info, sizeof(KEY)*s->keys);
 
5902
  s->key_info= key_info;
 
5903
  max_keys= s->keys+key_count;
 
5904
  return !(key_info);
 
5905
}
 
5906
 
 
5907
 
 
5908
void TABLE::create_key_part_by_field(KEY *keyinfo,
 
5909
                                     KEY_PART_INFO *key_part_info,
 
5910
                                     Field *field, uint fieldnr)
 
5911
{   
 
5912
  field->flags|= PART_KEY_FLAG;
 
5913
  key_part_info->null_bit= field->null_bit;
 
5914
  key_part_info->null_offset= (uint) (field->null_ptr -
 
5915
                                      (uchar*) record[0]);
 
5916
  key_part_info->field= field;
 
5917
  key_part_info->fieldnr= fieldnr;
 
5918
  key_part_info->offset= field->offset(record[0]);
 
5919
  key_part_info->length=   (uint16) field->pack_length();
 
5920
  keyinfo->key_length+= key_part_info->length;
 
5921
  key_part_info->key_part_flag= 0;
 
5922
  /* TODO:
 
5923
    The below method of computing the key format length of the
 
5924
    key part is a copy/paste from opt_range.cc, and table.cc.
 
5925
    This should be factored out, e.g. as a method of Field.
 
5926
    In addition it is not clear if any of the Field::*_length
 
5927
    methods is supposed to compute the same length. If so, it
 
5928
    might be reused.
 
5929
  */
 
5930
  key_part_info->store_length= key_part_info->length;
 
5931
 
 
5932
  if (field->real_maybe_null())
 
5933
  {
 
5934
    key_part_info->store_length+= HA_KEY_NULL_LENGTH;
 
5935
    keyinfo->key_length+= HA_KEY_NULL_LENGTH;
 
5936
  }
 
5937
  if (field->type() == MYSQL_TYPE_BLOB || 
 
5938
      field->type() == MYSQL_TYPE_GEOMETRY ||
 
5939
      field->real_type() == MYSQL_TYPE_VARCHAR)
 
5940
  {
 
5941
    key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
 
5942
    keyinfo->key_length+= HA_KEY_BLOB_LENGTH; // ???
 
5943
    key_part_info->key_part_flag|=
 
5944
      field->type() == MYSQL_TYPE_BLOB ? HA_BLOB_PART: HA_VAR_LENGTH_PART;
 
5945
  }
 
5946
 
 
5947
  key_part_info->type=     (uint8) field->key_type();
 
5948
  key_part_info->key_type =
 
5949
    ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
 
5950
    (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
 
5951
    (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
 
5952
    0 : FIELDFLAG_BINARY;
 
5953
}
 
5954
 
 
5955
 
 
5956
/**
 
5957
  @brief
 
5958
  Add one key to a temporary table
 
5959
 
 
5960
  @param key            the number of the key
 
5961
  @param key_parts      number of components of the key
 
5962
  @param next_field_no  the call-back function that returns the number of
 
5963
                        the field used as the next component of the key
 
5964
  @param arg            the argument for the above function
 
5965
  @param unique         TRUE <=> it is a unique index
 
5966
 
 
5967
  @details
 
5968
  The function adds a new key to the table that is assumed to be a temporary
 
5969
  table. At each its invocation the call-back function must return
 
5970
  the number of the field that is used as the next component of this key.
 
5971
 
 
5972
  @return FALSE is a success
 
5973
  @return TRUE if a failure
 
5974
 
 
5975
*/
 
5976
 
 
5977
bool TABLE::add_tmp_key(uint key, uint key_parts,
 
5978
                        uint (*next_field_no) (uchar *), uchar *arg,
 
5979
                        bool unique)
 
5980
{
 
5981
  DBUG_ASSERT(key < max_keys);
 
5982
 
 
5983
  char buf[NAME_CHAR_LEN];
 
5984
  KEY* keyinfo;
 
5985
  Field **reg_field;
 
5986
  uint i;
 
5987
  bool key_start= TRUE;
 
5988
  KEY_PART_INFO* key_part_info=
 
5989
      (KEY_PART_INFO*) alloc_root(&mem_root, sizeof(KEY_PART_INFO)*key_parts);
 
5990
  if (!key_part_info)
 
5991
    return TRUE;
 
5992
  keyinfo= key_info + key;
 
5993
  keyinfo->key_part= key_part_info;
 
5994
  keyinfo->usable_key_parts= keyinfo->key_parts = key_parts;
 
5995
  keyinfo->ext_key_parts= keyinfo->key_parts;
 
5996
  keyinfo->key_length=0;
 
5997
  keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
5998
  keyinfo->flags= HA_GENERATED_KEY;
 
5999
  keyinfo->ext_key_flags= keyinfo->flags;
 
6000
  if (unique)
 
6001
    keyinfo->flags|= HA_NOSAME;
 
6002
  sprintf(buf, "key%i", key);
 
6003
  if (!(keyinfo->name= strdup_root(&mem_root, buf)))
 
6004
    return TRUE;
 
6005
  keyinfo->rec_per_key= (ulong*) alloc_root(&mem_root,
 
6006
                                            sizeof(ulong)*key_parts);
 
6007
  if (!keyinfo->rec_per_key)
 
6008
    return TRUE;
 
6009
  bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
 
6010
 
 
6011
  for (i= 0; i < key_parts; i++)
 
6012
  {
 
6013
    uint fld_idx= next_field_no(arg); 
 
6014
    reg_field= field + fld_idx;
 
6015
    if (key_start)
 
6016
      (*reg_field)->key_start.set_bit(key);
 
6017
    (*reg_field)->part_of_key.set_bit(key);
 
6018
    create_key_part_by_field(keyinfo, key_part_info, *reg_field, fld_idx+1);
 
6019
    key_start= FALSE;
 
6020
    key_part_info++;
 
6021
  }
 
6022
 
 
6023
  set_if_bigger(s->max_key_length, keyinfo->key_length);
 
6024
  s->keys++;
 
6025
  return FALSE;
 
6026
}
 
6027
 
 
6028
/*
 
6029
  @brief
 
6030
  Drop all indexes except specified one.
 
6031
 
 
6032
  @param key_to_save the key to save
 
6033
 
 
6034
  @details
 
6035
  Drop all indexes on this table except 'key_to_save'. The saved key becomes
 
6036
  key #0. Memory occupied by key parts of dropped keys are freed.
 
6037
  If the 'key_to_save' is negative then all keys are freed.
 
6038
*/
 
6039
 
 
6040
void TABLE::use_index(int key_to_save)
 
6041
{
 
6042
  uint i= 1;
 
6043
  DBUG_ASSERT(!created && key_to_save < (int)s->keys);
 
6044
  if (key_to_save >= 0)
 
6045
    /* Save the given key. */
 
6046
    memmove(key_info, key_info + key_to_save, sizeof(KEY));
 
6047
  else
 
6048
    /* Drop all keys; */
 
6049
    i= 0;
 
6050
 
 
6051
  s->keys= i;
 
6052
}
 
6053
 
 
6054
/*
 
6055
  Return TRUE if the table is filled at execution phase 
 
6056
  
 
6057
  (and so, the optimizer must not do anything that depends on the contents of
 
6058
   the table, like range analysis or constant table detection)
 
6059
*/
 
6060
 
 
6061
bool TABLE::is_filled_at_execution()
 
6062
 
6063
  /*
 
6064
    pos_in_table_list == NULL for internal temporary tables because they
 
6065
    do not have a corresponding table reference. Such tables are filled
 
6066
    during execution.
 
6067
  */
 
6068
  return test(!pos_in_table_list ||
 
6069
              pos_in_table_list->jtbm_subselect || 
 
6070
              pos_in_table_list->is_active_sjm());
 
6071
}
 
6072
 
 
6073
 
 
6074
/**
 
6075
  @brief
 
6076
  Get actual number of key components
 
6077
 
 
6078
  @param keyinfo
 
6079
 
 
6080
  @details
 
6081
  The function calculates actual number of key components, possibly including
 
6082
  components of extended keys, taken into consideration by the optimizer for the
 
6083
  key described by the parameter keyinfo.
 
6084
 
 
6085
  @return number of considered key components
 
6086
*/ 
 
6087
 
 
6088
uint TABLE::actual_n_key_parts(KEY *keyinfo)
 
6089
{
 
6090
  return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
 
6091
           keyinfo->ext_key_parts : keyinfo->key_parts;
 
6092
}
 
6093
 
 
6094
 
 
6095
/**
 
6096
  @brief
 
6097
  Get actual key flags for a table key 
 
6098
 
 
6099
  @param keyinfo
 
6100
 
 
6101
  @details
 
6102
  The function finds out actual key flags taken into consideration by the
 
6103
  optimizer for the key described by the parameter keyinfo.
 
6104
 
 
6105
  @return actual key flags
 
6106
*/ 
 
6107
 
 
6108
ulong TABLE::actual_key_flags(KEY *keyinfo)
 
6109
{
 
6110
  return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
 
6111
           keyinfo->ext_key_flags : keyinfo->flags;
 
6112
 
6113
 
 
6114
 
 
6115
/*
 
6116
  Cleanup this table for re-execution.
 
6117
 
 
6118
  SYNOPSIS
 
6119
    TABLE_LIST::reinit_before_use()
 
6120
*/
 
6121
 
 
6122
void TABLE_LIST::reinit_before_use(THD *thd)
 
6123
{
 
6124
  /*
 
6125
    Reset old pointers to TABLEs: they are not valid since the tables
 
6126
    were closed in the end of previous prepare or execute call.
 
6127
  */
 
6128
  table= 0;
 
6129
  /* Reset is_schema_table_processed value(needed for I_S tables */
 
6130
  schema_table_state= NOT_PROCESSED;
 
6131
 
 
6132
  TABLE_LIST *embedded; /* The table at the current level of nesting. */
 
6133
  TABLE_LIST *parent_embedding= this; /* The parent nested table reference. */
 
6134
  do
 
6135
  {
 
6136
    embedded= parent_embedding;
 
6137
    if (embedded->prep_on_expr)
 
6138
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
 
6139
    parent_embedding= embedded->embedding;
 
6140
  }
 
6141
  while (parent_embedding &&
 
6142
         parent_embedding->nested_join->join_list.head() == embedded);
 
6143
 
 
6144
  mdl_request.ticket= NULL;
 
6145
}
 
6146
 
 
6147
 
 
6148
/*
 
6149
  Return subselect that contains the FROM list this table is taken from
 
6150
 
 
6151
  SYNOPSIS
 
6152
    TABLE_LIST::containing_subselect()
 
6153
 
 
6154
  RETURN
 
6155
    Subselect item for the subquery that contains the FROM list
 
6156
    this table is taken from if there is any
 
6157
    0 - otherwise
 
6158
 
 
6159
*/
 
6160
 
 
6161
Item_subselect *TABLE_LIST::containing_subselect()
 
6162
{    
 
6163
  return (select_lex ? select_lex->master_unit()->item : 0);
 
6164
}
 
6165
 
 
6166
/*
 
6167
  Compiles the tagged hints list and fills up the bitmasks.
 
6168
 
 
6169
  SYNOPSIS
 
6170
    process_index_hints()
 
6171
      table         the TABLE to operate on.
 
6172
 
 
6173
  DESCRIPTION
 
6174
    The parser collects the index hints for each table in a "tagged list" 
 
6175
    (TABLE_LIST::index_hints). Using the information in this tagged list
 
6176
    this function sets the members TABLE::keys_in_use_for_query,
 
6177
    TABLE::keys_in_use_for_group_by, TABLE::keys_in_use_for_order_by,
 
6178
    TABLE::force_index, TABLE::force_index_order,
 
6179
    TABLE::force_index_group and TABLE::covering_keys.
 
6180
 
 
6181
    Current implementation of the runtime does not allow mixing FORCE INDEX
 
6182
    and USE INDEX, so this is checked here. Then the FORCE INDEX list 
 
6183
    (if non-empty) is appended to the USE INDEX list and a flag is set.
 
6184
 
 
6185
    Multiple hints of the same kind are processed so that each clause 
 
6186
    is applied to what is computed in the previous clause.
 
6187
    For example:
 
6188
        USE INDEX (i1) USE INDEX (i2)
 
6189
    is equivalent to
 
6190
        USE INDEX (i1,i2)
 
6191
    and means "consider only i1 and i2".
 
6192
        
 
6193
    Similarly
 
6194
        USE INDEX () USE INDEX (i1)
 
6195
    is equivalent to
 
6196
        USE INDEX (i1)
 
6197
    and means "consider only the index i1"
 
6198
 
 
6199
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
 
6200
    not an error.
 
6201
        
 
6202
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
 
6203
    order:
 
6204
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
 
6205
      2. All IGNORE INDEX
 
6206
 
 
6207
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
 
6208
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
 
6209
 
 
6210
    As an optimization if there is a covering index, and we have 
 
6211
    IGNORE INDEX FOR GROUP/ORDER, and this index is used for the JOIN part, 
 
6212
    then we have to ignore the IGNORE INDEX FROM GROUP/ORDER.
 
6213
 
 
6214
  RETURN VALUE
 
6215
    FALSE                no errors found
 
6216
    TRUE                 found and reported an error.
 
6217
*/
 
6218
bool TABLE_LIST::process_index_hints(TABLE *tbl)
 
6219
{
 
6220
  /* initialize the result variables */
 
6221
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
 
6222
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
 
6223
 
 
6224
  /* index hint list processing */
 
6225
  if (index_hints)
 
6226
  {
 
6227
    key_map index_join[INDEX_HINT_FORCE + 1];
 
6228
    key_map index_order[INDEX_HINT_FORCE + 1];
 
6229
    key_map index_group[INDEX_HINT_FORCE + 1];
 
6230
    Index_hint *hint;
 
6231
    int type;
 
6232
    bool have_empty_use_join= FALSE, have_empty_use_order= FALSE, 
 
6233
         have_empty_use_group= FALSE;
 
6234
    List_iterator <Index_hint> iter(*index_hints);
 
6235
 
 
6236
    /* initialize temporary variables used to collect hints of each kind */
 
6237
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
 
6238
    {
 
6239
      index_join[type].clear_all();
 
6240
      index_order[type].clear_all();
 
6241
      index_group[type].clear_all();
 
6242
    }
 
6243
 
 
6244
    /* iterate over the hints list */
 
6245
    while ((hint= iter++))
 
6246
    {
 
6247
      uint pos;
 
6248
 
 
6249
      /* process empty USE INDEX () */
 
6250
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
 
6251
      {
 
6252
        if (hint->clause & INDEX_HINT_MASK_JOIN)
 
6253
        {
 
6254
          index_join[hint->type].clear_all();
 
6255
          have_empty_use_join= TRUE;
 
6256
        }
 
6257
        if (hint->clause & INDEX_HINT_MASK_ORDER)
 
6258
        {
 
6259
          index_order[hint->type].clear_all();
 
6260
          have_empty_use_order= TRUE;
 
6261
        }
 
6262
        if (hint->clause & INDEX_HINT_MASK_GROUP)
 
6263
        {
 
6264
          index_group[hint->type].clear_all();
 
6265
          have_empty_use_group= TRUE;
 
6266
        }
 
6267
        continue;
 
6268
      }
 
6269
 
 
6270
      /* 
 
6271
        Check if an index with the given name exists and get his offset in 
 
6272
        the keys bitmask for the table 
 
6273
      */
 
6274
      if (tbl->s->keynames.type_names == 0 ||
 
6275
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
 
6276
                          hint->key_name.length, 1)) <= 0)
 
6277
      {
 
6278
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
 
6279
        return 1;
 
6280
      }
 
6281
 
 
6282
      pos--;
 
6283
 
 
6284
      /* add to the appropriate clause mask */
 
6285
      if (hint->clause & INDEX_HINT_MASK_JOIN)
 
6286
        index_join[hint->type].set_bit (pos);
 
6287
      if (hint->clause & INDEX_HINT_MASK_ORDER)
 
6288
        index_order[hint->type].set_bit (pos);
 
6289
      if (hint->clause & INDEX_HINT_MASK_GROUP)
 
6290
        index_group[hint->type].set_bit (pos);
 
6291
    }
 
6292
 
 
6293
    /* cannot mix USE INDEX and FORCE INDEX */
 
6294
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
6295
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
6296
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
 
6297
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
 
6298
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
 
6299
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
 
6300
    {
 
6301
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
 
6302
               index_hint_type_name[INDEX_HINT_FORCE]);
 
6303
      return 1;
 
6304
    }
 
6305
 
 
6306
    /* process FORCE INDEX as USE INDEX with a flag */
 
6307
    if (!index_order[INDEX_HINT_FORCE].is_clear_all())
 
6308
    {
 
6309
      tbl->force_index_order= TRUE;
 
6310
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
 
6311
    }
 
6312
 
 
6313
    if (!index_group[INDEX_HINT_FORCE].is_clear_all())
 
6314
    {
 
6315
      tbl->force_index_group= TRUE;
 
6316
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
 
6317
    }
 
6318
 
 
6319
    /*
 
6320
      TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) and
 
6321
      create tbl->force_index_join instead.
 
6322
      Then use the correct force_index_XX instead of the global one.
 
6323
    */
 
6324
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
6325
        tbl->force_index_group || tbl->force_index_order)
 
6326
    {
 
6327
      tbl->force_index= TRUE;
 
6328
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
 
6329
    }
 
6330
 
 
6331
    /* apply USE INDEX */
 
6332
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
 
6333
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
 
6334
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
 
6335
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
 
6336
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
 
6337
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
 
6338
 
 
6339
    /* apply IGNORE INDEX */
 
6340
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
 
6341
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
 
6342
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
 
6343
  }
 
6344
 
 
6345
  /* make sure covering_keys don't include indexes disabled with a hint */
 
6346
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
 
6347
  return 0;
 
6348
}
 
6349
 
 
6350
 
 
6351
size_t max_row_length(TABLE *table, const uchar *data)
 
6352
{
 
6353
  TABLE_SHARE *table_s= table->s;
 
6354
  size_t length= table_s->reclength + 2 * table_s->fields;
 
6355
  uint *const beg= table_s->blob_field;
 
6356
  uint *const end= beg + table_s->blob_fields;
 
6357
 
 
6358
  for (uint *ptr= beg ; ptr != end ; ++ptr)
 
6359
  {
 
6360
    Field_blob* const blob= (Field_blob*) table->field[*ptr];
 
6361
    length+= blob->get_length((const uchar*)
 
6362
                              (data + blob->offset(table->record[0]))) +
 
6363
      HA_KEY_BLOB_LENGTH;
 
6364
  }
 
6365
  return length;
 
6366
}
 
6367
 
 
6368
 
 
6369
/**
 
6370
   Helper function which allows to allocate metadata lock request
 
6371
   objects for all elements of table list.
 
6372
*/
 
6373
 
 
6374
void init_mdl_requests(TABLE_LIST *table_list)
 
6375
{
 
6376
  for ( ; table_list ; table_list= table_list->next_global)
 
6377
    table_list->mdl_request.init(MDL_key::TABLE,
 
6378
                                 table_list->db, table_list->table_name,
 
6379
                                 table_list->lock_type >= TL_WRITE_ALLOW_WRITE ?
 
6380
                                 MDL_SHARED_WRITE : MDL_SHARED_READ,
 
6381
                                 MDL_TRANSACTION);
 
6382
}
 
6383
 
 
6384
 
 
6385
/**
 
6386
  Update TABLE::const_key_parts for single table UPDATE/DELETE query
 
6387
 
 
6388
  @param conds               WHERE clause expression
 
6389
 
 
6390
  @retval TRUE   error (OOM)
 
6391
  @retval FALSE  success
 
6392
 
 
6393
  @note
 
6394
    Set const_key_parts bits if key fields are equal to constants in
 
6395
    the WHERE expression.
 
6396
*/
 
6397
 
 
6398
bool TABLE::update_const_key_parts(COND *conds)
 
6399
{
 
6400
  bzero((char*) const_key_parts, sizeof(key_part_map) * s->keys);
 
6401
 
 
6402
  if (conds == NULL)
 
6403
    return FALSE;
 
6404
 
 
6405
  for (uint index= 0; index < s->keys; index++)
 
6406
  {
 
6407
    KEY_PART_INFO *keyinfo= key_info[index].key_part;
 
6408
    KEY_PART_INFO *keyinfo_end= keyinfo + key_info[index].key_parts;
 
6409
 
 
6410
    for (key_part_map part_map= (key_part_map)1; 
 
6411
        keyinfo < keyinfo_end;
 
6412
        keyinfo++, part_map<<= 1)
 
6413
    {
 
6414
      if (const_expression_in_where(conds, NULL, keyinfo->field))
 
6415
        const_key_parts[index]|= part_map;
 
6416
    }
 
6417
  }
 
6418
  return FALSE;
 
6419
}
 
6420
 
 
6421
/**
 
6422
  Test if the order list consists of simple field expressions
 
6423
 
 
6424
  @param order                Linked list of ORDER BY arguments
 
6425
 
 
6426
  @return TRUE if @a order is empty or consist of simple field expressions
 
6427
*/
 
6428
 
 
6429
bool is_simple_order(ORDER *order)
 
6430
{
 
6431
  for (ORDER *ord= order; ord; ord= ord->next)
 
6432
  {
 
6433
    if (ord->item[0]->real_item()->type() != Item::FIELD_ITEM)
 
6434
      return FALSE;
 
6435
  }
 
6436
  return TRUE;
 
6437
}
 
6438
 
 
6439
/*
 
6440
  @brief Compute values for virtual columns used in query
 
6441
 
 
6442
  @param  thd              Thread handle
 
6443
  @param  table            The TABLE object
 
6444
  @param  vcol_update_mode Specifies what virtual column are computed   
 
6445
  
 
6446
  @details
 
6447
    The function computes the values of the virtual columns of the table and
 
6448
    stores them in the table record buffer.
 
6449
    If vcol_update_mode is set to VCOL_UPDATE_ALL then all virtual column are
 
6450
    computed. Otherwise, only fields from vcol_set are computed: all of them,
 
6451
    if vcol_update_mode is set to VCOL_UPDATE_FOR_WRITE, and, only those with
 
6452
    the stored_in_db flag set to false, if vcol_update_mode is equal to
 
6453
    VCOL_UPDATE_FOR_READ.
 
6454
 
 
6455
  @retval
 
6456
    0    Success
 
6457
  @retval
 
6458
    >0   Error occurred when storing a virtual field value
 
6459
*/
 
6460
 
 
6461
int update_virtual_fields(THD *thd, TABLE *table,
 
6462
                          enum enum_vcol_update_mode vcol_update_mode)
 
6463
{
 
6464
  DBUG_ENTER("update_virtual_fields");
 
6465
  Field **vfield_ptr, *vfield;
 
6466
  int error __attribute__ ((unused))= 0;
 
6467
  DBUG_ASSERT(table && table->vfield);
 
6468
 
 
6469
  thd->reset_arena_for_cached_items(table->expr_arena);
 
6470
  /* Iterate over virtual fields in the table */
 
6471
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
6472
  {
 
6473
    vfield= (*vfield_ptr);
 
6474
    DBUG_ASSERT(vfield->vcol_info && vfield->vcol_info->expr_item);
 
6475
    if ((bitmap_is_set(table->vcol_set, vfield->field_index) &&
 
6476
         (vcol_update_mode == VCOL_UPDATE_FOR_WRITE || !vfield->stored_in_db)) ||
 
6477
        vcol_update_mode == VCOL_UPDATE_ALL)
 
6478
    {
 
6479
      /* Compute the actual value of the virtual fields */
 
6480
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
6481
      DBUG_PRINT("info", ("field '%s' - updated", vfield->field_name));
 
6482
    }
 
6483
    else
 
6484
    {
 
6485
      DBUG_PRINT("info", ("field '%s' - skipped", vfield->field_name));
 
6486
    }
 
6487
  }
 
6488
  thd->reset_arena_for_cached_items(0);
 
6489
  DBUG_RETURN(0);
 
6490
}
 
6491
 
 
6492
/*
 
6493
  @brief Reset const_table flag
 
6494
 
 
6495
  @detail
 
6496
  Reset const_table flag for this table. If this table is a merged derived
 
6497
  table/view the flag is recursively reseted for all tables of the underlying
 
6498
  select.
 
6499
*/
 
6500
 
 
6501
void TABLE_LIST::reset_const_table()
 
6502
{
 
6503
  table->const_table= 0;
 
6504
  if (is_merged_derived())
 
6505
  {
 
6506
    SELECT_LEX *select_lex= get_unit()->first_select();
 
6507
    TABLE_LIST *tl;
 
6508
    List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
 
6509
    while ((tl= ti++))
 
6510
      tl->reset_const_table();
 
6511
  }
 
6512
}
 
6513
 
 
6514
 
 
6515
/*
 
6516
  @brief Run derived tables/view handling phases on underlying select_lex.
 
6517
 
 
6518
  @param lex    LEX for this thread
 
6519
  @param phases derived tables/views handling phases to run
 
6520
                (set of DT_XXX constants)
 
6521
  @details
 
6522
  This function runs this derived table through specified 'phases'.
 
6523
  Underlying tables of this select are handled prior to this derived.
 
6524
  'lex' is passed as an argument to called functions.
 
6525
 
 
6526
  @return TRUE on error
 
6527
  @return FALSE ok
 
6528
*/
 
6529
 
 
6530
bool TABLE_LIST::handle_derived(LEX *lex, uint phases)
 
6531
{
 
6532
  SELECT_LEX_UNIT *unit= get_unit();
 
6533
  if (unit)
 
6534
  {
 
6535
    for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
 
6536
      if (sl->handle_derived(lex, phases))
 
6537
        return TRUE;
 
6538
    return mysql_handle_single_derived(lex, this, phases);
 
6539
  }
 
6540
  return FALSE;
 
6541
}
 
6542
 
 
6543
 
 
6544
/**
 
6545
  @brief
 
6546
  Return unit of this derived table/view
 
6547
 
 
6548
  @return reference to a unit  if it's a derived table/view.
 
6549
  @return 0                    when it's not a derived table/view.
 
6550
*/
 
6551
 
 
6552
st_select_lex_unit *TABLE_LIST::get_unit()
 
6553
{
 
6554
  return (view ? &view->unit : derived);
 
6555
}
 
6556
 
 
6557
 
 
6558
/**
 
6559
  @brief
 
6560
  Return select_lex of this derived table/view
 
6561
 
 
6562
  @return select_lex of this derived table/view.
 
6563
  @return 0          when it's not a derived table.
 
6564
*/
 
6565
 
 
6566
st_select_lex *TABLE_LIST::get_single_select()
 
6567
{
 
6568
  SELECT_LEX_UNIT *unit= get_unit();
 
6569
  return (unit ? unit->first_select() : 0);
 
6570
}
 
6571
 
 
6572
 
 
6573
/**
 
6574
  @brief
 
6575
  Attach a join table list as a nested join to this TABLE_LIST.
 
6576
 
 
6577
  @param join_list join table list to attach
 
6578
 
 
6579
  @details
 
6580
  This function wraps 'join_list' into a nested_join of this table, thus
 
6581
  turning it to a nested join leaf.
 
6582
*/
 
6583
 
 
6584
void TABLE_LIST::wrap_into_nested_join(List<TABLE_LIST> &join_list)
 
6585
{
 
6586
  TABLE_LIST *tl;
 
6587
  /*
 
6588
    Walk through derived table top list and set 'embedding' to point to
 
6589
    the nesting table.
 
6590
  */
 
6591
  nested_join->join_list.empty();
 
6592
  List_iterator_fast<TABLE_LIST> li(join_list);
 
6593
  nested_join->join_list= join_list;
 
6594
  while ((tl= li++))
 
6595
  {
 
6596
    tl->embedding= this;
 
6597
    tl->join_list= &nested_join->join_list;
 
6598
  }
 
6599
}
 
6600
 
 
6601
 
 
6602
/**
 
6603
  @brief
 
6604
  Initialize this derived table/view
 
6605
 
 
6606
  @param thd  Thread handle
 
6607
 
 
6608
  @details
 
6609
  This function makes initial preparations of this derived table/view for
 
6610
  further processing:
 
6611
    if it's a derived table this function marks it either as mergeable or
 
6612
      materializable
 
6613
    creates temporary table for name resolution purposes
 
6614
    creates field translation for mergeable derived table/view
 
6615
 
 
6616
  @return TRUE  an error occur
 
6617
  @return FALSE ok
 
6618
*/
 
6619
 
 
6620
bool TABLE_LIST::init_derived(THD *thd, bool init_view)
 
6621
{
 
6622
  SELECT_LEX *first_select= get_single_select();
 
6623
  SELECT_LEX_UNIT *unit= get_unit();
 
6624
 
 
6625
  if (!unit)
 
6626
    return FALSE;
 
6627
  /*
 
6628
    Check whether we can merge this derived table into main select.
 
6629
    Depending on the result field translation will or will not
 
6630
    be created.
 
6631
  */
 
6632
  TABLE_LIST *first_table= (TABLE_LIST *) first_select->table_list.first;
 
6633
  if (first_select->table_list.elements > 1 ||
 
6634
      (first_table && first_table->is_multitable()))
 
6635
    set_multitable();
 
6636
 
 
6637
  unit->derived= this;
 
6638
  if (init_view && !view)
 
6639
  {
 
6640
    /* This is all what we can do for a derived table for now. */
 
6641
    set_derived();
 
6642
  }
 
6643
 
 
6644
  if (!is_view())
 
6645
  {
 
6646
    /* A subquery might be forced to be materialized due to a side-effect. */
 
6647
    if (!is_materialized_derived() && first_select->is_mergeable() &&
 
6648
        optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_MERGE) &&
 
6649
        !(thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
 
6650
          thd->lex->sql_command == SQLCOM_DELETE_MULTI))
 
6651
      set_merged_derived();
 
6652
    else
 
6653
      set_materialized_derived();
 
6654
  }
 
6655
  /*
 
6656
    Derived tables/view are materialized prior to UPDATE, thus we can skip
 
6657
    them from table uniqueness check
 
6658
  */
 
6659
  if (is_materialized_derived())
 
6660
  {
 
6661
    set_check_materialized();
 
6662
  }
 
6663
 
 
6664
  /*
 
6665
    Create field translation for mergeable derived tables/views.
 
6666
    For derived tables field translation can be created only after
 
6667
    unit is prepared so all '*' are get unrolled.
 
6668
  */
 
6669
  if (is_merged_derived())
 
6670
  {
 
6671
    if (is_view() || unit->prepared)
 
6672
      create_field_translation(thd);
 
6673
  }
 
6674
 
 
6675
  return FALSE;
 
6676
}
 
6677
 
 
6678
 
 
6679
/**
 
6680
  @brief
 
6681
  Retrieve number of rows in the table
 
6682
 
 
6683
  @details
 
6684
  Retrieve number of rows in the table referred by this TABLE_LIST and
 
6685
  store it in the table's stats.records variable. If this TABLE_LIST refers
 
6686
  to a materialized derived table/view then the estimated number of rows of
 
6687
  the derived table/view is used instead.
 
6688
 
 
6689
  @return 0          ok
 
6690
  @return non zero   error
 
6691
*/
 
6692
 
 
6693
int TABLE_LIST::fetch_number_of_rows()
 
6694
{
 
6695
  int error= 0;
 
6696
  if (jtbm_subselect)
 
6697
    return 0;
 
6698
  if (is_materialized_derived() && !fill_me)
 
6699
 
 
6700
  {
 
6701
    table->file->stats.records= ((select_union*)derived->result)->records;
 
6702
    set_if_bigger(table->file->stats.records, 2);
 
6703
  }
 
6704
  else
 
6705
    error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
6706
  return error;
 
6707
}
 
6708
 
 
6709
/*
 
6710
  Procedure of keys generation for result tables of materialized derived
 
6711
  tables/views.
 
6712
 
 
6713
  A key is generated for each equi-join pair derived table-another table.
 
6714
  Each generated key consists of fields of derived table used in equi-join.
 
6715
  Example:
 
6716
 
 
6717
    SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
 
6718
                  t1 ON tt.f1=t1.f3 and tt.f2.=t1.f4;
 
6719
  In this case for the derived table tt one key will be generated. It will
 
6720
  consist of two parts f1 and f2.
 
6721
  Example:
 
6722
 
 
6723
    SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
 
6724
                  t1 ON tt.f1=t1.f3 JOIN
 
6725
                  t2 ON tt.f2=t2.f4;
 
6726
  In this case for the derived table tt two keys will be generated.
 
6727
  One key over f1 field, and another key over f2 field.
 
6728
  Currently optimizer may choose to use only one such key, thus the second
 
6729
  one will be dropped after range optimizer is finished.
 
6730
  See also JOIN::drop_unused_derived_keys function.
 
6731
  Example:
 
6732
 
 
6733
    SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
 
6734
                  t1 ON tt.f1=a_function(t1.f3);
 
6735
  In this case for the derived table tt one key will be generated. It will
 
6736
  consist of one field - f1.
 
6737
*/
 
6738
 
 
6739
 
 
6740
 
 
6741
/*
 
6742
  @brief
 
6743
  Change references to underlying items of a merged derived table/view
 
6744
  for fields in derived table's result table.
 
6745
 
 
6746
  @return FALSE ok
 
6747
  @return TRUE  Out of memory
 
6748
*/
 
6749
bool TABLE_LIST::change_refs_to_fields()
 
6750
{
 
6751
  List_iterator<Item> li(used_items);
 
6752
  Item_direct_ref *ref;
 
6753
  Field_iterator_view field_it;
 
6754
  THD *thd= table->in_use;
 
6755
  DBUG_ASSERT(is_merged_derived());
 
6756
 
 
6757
  if (!used_items.elements)
 
6758
    return FALSE;
 
6759
 
 
6760
  materialized_items= (Item**)thd->calloc(sizeof(void*) * table->s->fields);
 
6761
 
 
6762
  while ((ref= (Item_direct_ref*)li++))
 
6763
  {
 
6764
    uint idx;
 
6765
    Item *orig_item= *ref->ref;
 
6766
    field_it.set(this);
 
6767
    for (idx= 0; !field_it.end_of_fields(); field_it.next(), idx++)
 
6768
    {
 
6769
      if (field_it.item() == orig_item)
 
6770
        break;
 
6771
    }
 
6772
    DBUG_ASSERT(!field_it.end_of_fields());
 
6773
    if (!materialized_items[idx])
 
6774
    {
 
6775
      materialized_items[idx]= new Item_field(table->field[idx]);
 
6776
      if (!materialized_items[idx])
 
6777
        return TRUE;
 
6778
    }
 
6779
    /*
 
6780
      We need to restore the pointers after the execution of the
 
6781
      prepared statement.
 
6782
    */
 
6783
    thd->change_item_tree((Item **)&ref->ref,
 
6784
                          (Item*)(materialized_items + idx));
 
6785
  }
 
6786
 
 
6787
  return FALSE;
 
6788
}
 
6789
 
 
6790
 
 
6791
uint TABLE_SHARE::actual_n_key_parts(THD *thd)
 
6792
{
 
6793
  return use_ext_keys &&
 
6794
         optimizer_flag(thd, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
 
6795
           ext_key_parts : key_parts;
 
6796
}  
 
6797
 
 
6798
 
 
6799
/*****************************************************************************
 
6800
** Instansiate templates
 
6801
*****************************************************************************/
 
6802
 
 
6803
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
6804
template class List<String>;
 
6805
template class List_iterator<String>;
 
6806
#endif