~ubuntu-branches/ubuntu/natty/mysql-5.1/natty-proposed

« back to all changes in this revision

Viewing changes to sql/sql_base.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 08:30:45 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120222083045-2rd53r4bnyx7qus4
Tags: 5.1.61-0ubuntu0.11.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
1
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
96
96
static pthread_mutex_t LOCK_table_share;
97
97
static bool table_def_inited= 0;
98
98
 
 
99
/**
 
100
  Dummy TABLE instance which is used in reopen_tables() and reattach_merge()
 
101
  functions to mark MERGE tables and their children with which there is some
 
102
  kind of problem and which therefore we need to close.
 
103
*/
 
104
static TABLE bad_merge_marker;
 
105
 
99
106
static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list,
100
107
                             const char *alias,
101
108
                             char *cache_key, uint cache_key_length,
2798
2805
                 ("Found table '%s.%s' with different refresh version",
2799
2806
                  table_list->db, table_list->table_name));
2800
2807
 
2801
 
      /* Ignore FLUSH, but not name locks! */
 
2808
      /* Ignore FLUSH and pending name locks, but not acquired name locks! */
2802
2809
      if (flags & MYSQL_LOCK_IGNORE_FLUSH && !table->open_placeholder)
2803
2810
      {
2804
 
        DBUG_ASSERT(table->db_stat);
2805
2811
        /* Force close at once after usage */
2806
2812
        thd->version= table->s->version;
2807
2813
        continue;
2993
2999
  table->insert_values= 0;
2994
3000
  table->fulltext_searched= 0;
2995
3001
  table->file->ft_handler= 0;
 
3002
  /*
 
3003
    Check that there is no reference to a condtion from an earlier query
 
3004
    (cf. Bug#58553). 
 
3005
  */
 
3006
  DBUG_ASSERT(table->file->pushed_cond == NULL);
2996
3007
  table->reginfo.impossible_range= 0;
2997
3008
  /* Catch wrong handling of the auto_increment_field_not_null. */
2998
3009
  DBUG_ASSERT(!table->auto_increment_field_not_null);
3211
3222
 
3212
3223
 
3213
3224
/**
 
3225
  @brief Mark merge parent and children with bad_merge_marker
 
3226
 
 
3227
  @param[in,out]  parent       the TABLE object of the parent
 
3228
*/
 
3229
 
 
3230
static void mark_merge_parent_and_children_as_bad(TABLE *parent)
 
3231
{
 
3232
  TABLE_LIST *child_l;
 
3233
  DBUG_ENTER("mark_merge_parent_and_children_as_bad");
 
3234
  parent->parent= &bad_merge_marker;
 
3235
  for (child_l= parent->child_l; ; child_l= child_l->next_global)
 
3236
  {
 
3237
    child_l->table->parent= &bad_merge_marker;
 
3238
    child_l->table= NULL;
 
3239
    if (&child_l->next_global == parent->child_last_l)
 
3240
      break;
 
3241
  }
 
3242
  DBUG_VOID_RETURN;
 
3243
}
 
3244
 
 
3245
 
 
3246
/**
3214
3247
  Reattach MERGE children after reopen.
3215
3248
 
3216
3249
  @param[in]     thd            thread context
3217
 
  @param[in,out] err_tables_p   pointer to pointer of tables in error
 
3250
 
 
3251
  @note If reattach failed for certain MERGE table, the table (and all
 
3252
        it's children) are marked with bad_merge_marker.
3218
3253
 
3219
3254
  @return       status
3220
 
    @retval     FALSE           OK, err_tables_p unchanged
3221
 
    @retval     TRUE            Error, err_tables_p contains table(s)
 
3255
    @retval     FALSE           OK
 
3256
    @retval     TRUE            Error
3222
3257
*/
3223
3258
 
3224
 
static bool reattach_merge(THD *thd, TABLE **err_tables_p)
 
3259
static bool reattach_merge(THD *thd)
3225
3260
{
3226
3261
  TABLE *table;
3227
 
  TABLE *next;
3228
 
  TABLE **prv_p= &thd->open_tables;
3229
3262
  bool error= FALSE;
3230
3263
  DBUG_ENTER("reattach_merge");
3231
3264
 
3232
 
  for (table= thd->open_tables; table; table= next)
 
3265
  for (table= thd->open_tables; table; table= table->next)
3233
3266
  {
3234
 
    next= table->next;
3235
 
    DBUG_PRINT("tcache", ("check table: '%s'.'%s' 0x%lx  next: 0x%lx",
 
3267
    DBUG_PRINT("tcache", ("check table: '%s'.'%s' 0x%lx",
3236
3268
                          table->s->db.str, table->s->table_name.str,
3237
 
                          (long) table, (long) next));
3238
 
    /* Reattach children for MERGE tables with "closed data files" only. */
3239
 
    if (table->child_l && !table->children_attached)
 
3269
                          (long) table));
 
3270
    /*
 
3271
      Reattach children only for MERGE tables that had children or parent
 
3272
      with "closed data files" and were reopen. For extra safety skip MERGE
 
3273
      tables which we failed to reopen (should not happen with current code).
 
3274
    */
 
3275
    if (table->child_l && table->parent != &bad_merge_marker &&
 
3276
        !table->children_attached)
3240
3277
    {
3241
3278
      DBUG_PRINT("tcache", ("MERGE parent, attach children"));
3242
 
      if(table->file->extra(HA_EXTRA_ATTACH_CHILDREN))
 
3279
      if (table->file->extra(HA_EXTRA_ATTACH_CHILDREN))
3243
3280
      {
3244
3281
        my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
3245
3282
        error= TRUE;
3246
 
        /* Remove table from open_tables. */
3247
 
        *prv_p= next;
3248
 
        if (next)
3249
 
          prv_p= &next->next;
3250
 
        /* Stack table on error list. */
3251
 
        table->next= *err_tables_p;
3252
 
        *err_tables_p= table;
3253
 
        continue;
 
3283
        mark_merge_parent_and_children_as_bad(table);
3254
3284
      }
3255
3285
      else
3256
3286
      {
3260
3290
                            table->s->table_name.str, (long) table));
3261
3291
      }
3262
3292
    }
3263
 
    prv_p= &table->next;
3264
3293
  }
3265
3294
  DBUG_RETURN(error);
3266
3295
}
3290
3319
{
3291
3320
  TABLE *table,*next,**prev;
3292
3321
  TABLE **tables,**tables_ptr;                  // For locks
3293
 
  TABLE *err_tables= NULL;
3294
3322
  bool error=0, not_used;
3295
3323
  bool merge_table_found= FALSE;
3296
3324
  const uint flags= MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN |
3324
3352
  for (table=thd->open_tables; table ; table=next)
3325
3353
  {
3326
3354
    uint db_stat=table->db_stat;
 
3355
    TABLE *parent= table->child_l ? table : table->parent;
3327
3356
    next=table->next;
3328
3357
    DBUG_PRINT("tcache", ("open table: '%s'.'%s' 0x%lx  "
3329
3358
                          "parent: 0x%lx  db_stat: %u",
3330
3359
                          table->s->db.str, table->s->table_name.str,
3331
3360
                          (long) table, (long) table->parent, db_stat));
3332
 
    if (table->child_l && !db_stat)
 
3361
    /*
 
3362
      If we need to reopen child or parent table in a MERGE table, then
 
3363
      children in this MERGE table has to be already detached at this
 
3364
      point.
 
3365
    */
 
3366
    DBUG_ASSERT(db_stat || !parent || !parent->children_attached);
 
3367
    /*
 
3368
      Thanks to the above assumption the below condition will guarantee that
 
3369
      merge_table_found is TRUE when we need to reopen child or parent table.
 
3370
      Note that it works even in situation when it is only a child and not a
 
3371
      parent that needs reopen (this can happen when get_locks == FALSE).
 
3372
    */
 
3373
    if (table->child_l && !table->children_attached)
3333
3374
      merge_table_found= TRUE;
3334
 
    if (!tables || (!db_stat && reopen_table(table)))
 
3375
 
 
3376
    if (!tables)
3335
3377
    {
3336
 
      my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
3337
3378
      /*
3338
 
        If we could not allocate 'tables', we may close open tables
3339
 
        here. If a MERGE table is affected, detach the children first.
3340
 
        It is not necessary to clear the child or parent table reference
3341
 
        of this table because the TABLE is freed. But we need to clear
3342
 
        the child or parent references of the other belonging tables so
3343
 
        that they cannot be moved into the unused_tables chain with
3344
 
        these pointers set.
 
3379
        If we could not allocate 'tables' we close ALL open tables here.
 
3380
        Before closing MERGE child or parent we need to detach children
 
3381
        and/or clear references in/to them.
3345
3382
      */
3346
 
      if (table->child_l || table->parent)
 
3383
      if (parent)
3347
3384
        detach_merge_children(table, TRUE);
3348
 
      VOID(hash_delete(&open_cache,(uchar*) table));
3349
 
      error=1;
 
3385
    }
 
3386
    else if (table->parent == &bad_merge_marker)
 
3387
    {
 
3388
      /*
 
3389
        This is either a child or a parent of a MERGE table for which
 
3390
        we already decided that we are unable to reopen it. Close it.
 
3391
 
 
3392
        Reset parent reference, it may be used while freeing the table.
 
3393
      */
 
3394
      table->parent= NULL;
 
3395
    }
 
3396
    else if (!db_stat && reopen_table(table))
 
3397
    {
 
3398
      /*
 
3399
        If we fail to reopen a child or a parent in a MERGE table and the
 
3400
        MERGE table is affected for the first time, mark all relevant tables
 
3401
        invalid. Otherwise handle it as usual.
 
3402
 
 
3403
        All in all we must end up with:
 
3404
        - child tables are detached from parent. This was done earlier,
 
3405
          but child<->parent references were kept valid for reopen.
 
3406
        - parent is not in the to-be-locked tables
 
3407
        - all child tables and parent are not in the THD::open_tables.
 
3408
        - all child tables and parent are not in the open_cache.
 
3409
 
 
3410
        Please note that below we do additional pass through THD::open_tables
 
3411
        list to achieve the last three points.
 
3412
      */
 
3413
      if (parent)
 
3414
      {
 
3415
        mark_merge_parent_and_children_as_bad(parent);
 
3416
        table->parent= NULL;
 
3417
      }
3350
3418
    }
3351
3419
    else
3352
3420
    {
3362
3430
        table->s->version=0;
3363
3431
        table->open_placeholder= 0;
3364
3432
      }
 
3433
      continue;
3365
3434
    }
 
3435
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
 
3436
    VOID(hash_delete(&open_cache, (uchar *) table));
 
3437
    error= 1;
3366
3438
  }
3367
3439
  *prev=0;
3368
3440
  /*
3369
3441
    When all tables are open again, we can re-attach MERGE children to
3370
 
    their parents. All TABLE objects are still present.
 
3442
    their parents.
 
3443
 
 
3444
    If there was an error while reopening a child or a parent of a MERGE
 
3445
    table, or while reattaching child tables to their parents, some tables
 
3446
    may have been kept open but marked for close with bad_merge_marker.
 
3447
    Close these tables now.
3371
3448
  */
3372
 
  DBUG_PRINT("tcache", ("re-attaching MERGE tables: %d", merge_table_found));
3373
 
  if (!error && merge_table_found && reattach_merge(thd, &err_tables))
 
3449
  if (tables && merge_table_found && (error|= reattach_merge(thd)))
3374
3450
  {
3375
 
    while (err_tables)
 
3451
    prev= &thd->open_tables;
 
3452
    for (table= thd->open_tables; table; table= next)
3376
3453
    {
3377
 
      VOID(hash_delete(&open_cache, (uchar*) err_tables));
3378
 
      err_tables= err_tables->next;
 
3454
      next= table->next;
 
3455
      if (table->parent == &bad_merge_marker)
 
3456
      {
 
3457
        /* Remove merge parent from to-be-locked tables array. */
 
3458
        if (get_locks && table->child_l)
 
3459
        {
 
3460
          TABLE **t;
 
3461
          for (t= tables; t < tables_ptr; t++)
 
3462
          {
 
3463
            if (*t == table)
 
3464
            {
 
3465
              tables_ptr--;
 
3466
              memmove(t, t + 1, (tables_ptr - t) * sizeof(TABLE *));
 
3467
              break;
 
3468
            }
 
3469
          }
 
3470
        }
 
3471
        /* Reset parent reference, it may be used while freeing the table. */
 
3472
        table->parent= NULL;
 
3473
        /* Free table. */
 
3474
        VOID(hash_delete(&open_cache, (uchar *) table));
 
3475
      }
 
3476
      else
 
3477
      {
 
3478
        *prev= table;
 
3479
        prev= &table->next;
 
3480
      }
3379
3481
    }
 
3482
    *prev= 0;
3380
3483
  }
3381
3484
  DBUG_PRINT("tcache", ("open tables to lock: %u",
3382
3485
                        (uint) (tables_ptr - tables)));
4004
4107
     {
4005
4108
       /* Give right error message */
4006
4109
       thd->clear_error();
4007
 
       my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
 
4110
       my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str);
4008
4111
       sql_print_error("Couldn't repair table: %s.%s", share->db.str,
4009
4112
                       share->table_name.str);
4010
4113
       if (entry->file)
5936
6039
/*
5937
6040
  Find field by name in a base table or a view with temp table algorithm.
5938
6041
 
 
6042
  The caller is expected to check column-level privileges.
 
6043
 
5939
6044
  SYNOPSIS
5940
6045
    find_field_in_table()
5941
6046
    thd                         thread handler
6043
6148
    This procedure detects the type of the table reference 'table_list'
6044
6149
    and calls the corresponding search routine.
6045
6150
 
 
6151
    The routine checks column-level privieleges for the found field.
 
6152
 
6046
6153
  RETURN
6047
6154
    0                   field is not found
6048
6155
    view_ref_found      found value in VIEW (real result is in *ref)
6316
6423
      when table_ref->field_translation != NULL.
6317
6424
      */
6318
6425
    if (table_ref->table && !table_ref->view)
 
6426
    {
6319
6427
      found= find_field_in_table(thd, table_ref->table, name, length,
6320
6428
                                 TRUE, &(item->cached_field_index));
 
6429
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
6430
      /* Check if there are sufficient access rights to the found field. */
 
6431
      if (found && check_privileges &&
 
6432
          check_column_grant_in_table_ref(thd, table_ref, name, length))
 
6433
        found= WRONG_GRANT;
 
6434
#endif
 
6435
    }
6321
6436
    else
6322
6437
      found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
6323
6438
                                     NULL, NULL, ref, check_privileges,
7560
7675
    if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
7561
7676
        sum_func_list)
7562
7677
      item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
7563
 
    thd->used_tables|= item->used_tables();
 
7678
    thd->lex->used_tables|= item->used_tables();
7564
7679
    thd->lex->current_select->cur_pos_in_select_list++;
7565
7680
  }
7566
7681
  thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
7670
7785
  }
7671
7786
  if (tablenr > MAX_TABLES)
7672
7787
  {
7673
 
    my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
 
7788
    my_error(ER_TOO_MANY_TABLES, MYF(0), static_cast<int>(MAX_TABLES));
7674
7789
    DBUG_RETURN(1);
7675
7790
  }
7676
7791
  for (table_list= tables;
7907
8022
      views and natural joins this update is performed inside the loop below.
7908
8023
    */
7909
8024
    if (table)
7910
 
      thd->used_tables|= table->map;
 
8025
      thd->lex->used_tables|= table->map;
7911
8026
 
7912
8027
    /*
7913
8028
      Initialize a generic field iterator for the current table reference.
7992
8107
          field_table= nj_col->table_ref->table;
7993
8108
          if (field_table)
7994
8109
          {
7995
 
            thd->used_tables|= field_table->map;
 
8110
            thd->lex->used_tables|= field_table->map;
7996
8111
            field_table->covering_keys.intersect(field->part_of_key);
7997
8112
            field_table->merge_keys.merge(field->part_of_key);
7998
8113
            field_table->used_fields++;
8000
8115
        }
8001
8116
      }
8002
8117
      else
8003
 
        thd->used_tables|= item->used_tables();
 
8118
        thd->lex->used_tables|= item->used_tables();
8004
8119
      thd->lex->current_select->cur_pos_in_select_list++;
8005
8120
    }
8006
8121
    /*