~ubuntu-branches/ubuntu/gutsy/mysql-dfsg-5.0/gutsy

« back to all changes in this revision

Viewing changes to libmysqld/log_event.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2007-04-03 09:43:01 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20070403094301-fnjhfr59hu72pvtg
Tags: 5.0.38-0ubuntu1
* Package the Enterprise version again (.37 was a community version), since
  Debian and we have always done so. This brings in a few more bug fixes and
  makes functional derivations less likely.
* debian/README.Maintainer: Add pointer to upstream download URL, since it
  is very hard to find the Enterprise versions.
* Disable 33_scripts__mysql_create_system_tables__no_test.dpatch, since that
  script was removed upstream.
* debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch: Adapted to
  changed formatting in new upstream version.
* Remove debian/patches/86_PATH_MAX.dpatch, fixed upstream.
* Add debian/patches/90_org_tables_definition.dpatch: Fix local variable
  declaration in libmysqld/sql_parse.cc to fix compilation with
  EMBEDDED_LIBRARY.

Show diffs side-by-side

added added

removed removed

Lines of Context:
269
269
}
270
270
#endif
271
271
 
 
272
 
272
273
/*
273
274
  Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
274
275
  commands just before it prints a query.
275
276
*/
276
277
 
 
278
#ifdef MYSQL_CLIENT
 
279
 
277
280
static void print_set_option(FILE* file, uint32 bits_changed, uint32 option,
278
281
                             uint32 flags, const char* name, bool* need_comma) 
279
282
{
285
288
    *need_comma= 1;
286
289
  }
287
290
}
 
291
#endif
288
292
 
289
293
/**************************************************************************
290
294
        Log_event methods (= the parent class of all events)
1088
1092
            1+4+           // code of autoinc and the 2 autoinc variables
1089
1093
            1+6+           // code of charset and charset
1090
1094
            1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
1091
 
            1+2            // code of lc_time_names and lc_time_names_number
 
1095
            1+2+           // code of lc_time_names and lc_time_names_number
 
1096
            1+2            // code of charset_database and charset_database_number
1092
1097
            ], *start, *start_of_status;
1093
1098
  ulong event_length;
1094
1099
 
1207
1212
    int2store(start, lc_time_names_number);
1208
1213
    start+= 2;
1209
1214
  }
 
1215
  if (charset_database_number)
 
1216
  {
 
1217
    DBUG_ASSERT(charset_database_number <= 0xFFFF);
 
1218
    *start++= Q_CHARSET_DATABASE_CODE;
 
1219
    int2store(start, charset_database_number);
 
1220
    start+= 2;
 
1221
  }
1210
1222
  /*
1211
1223
    Here there could be code like
1212
1224
    if (command-line-option-which-says-"log_this_variable" && inited)
1272
1284
   sql_mode(thd_arg->variables.sql_mode),
1273
1285
   auto_increment_increment(thd_arg->variables.auto_increment_increment),
1274
1286
   auto_increment_offset(thd_arg->variables.auto_increment_offset),
1275
 
   lc_time_names_number(thd_arg->variables.lc_time_names->number)
 
1287
   lc_time_names_number(thd_arg->variables.lc_time_names->number),
 
1288
   charset_database_number(0)
1276
1289
{
1277
1290
  time_t end_time;
1278
1291
  time(&end_time);
1280
1293
  catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
1281
1294
  /* status_vars_len is set just before writing the event */
1282
1295
  db_len = (db) ? (uint32) strlen(db) : 0;
 
1296
  if (thd_arg->variables.collation_database != thd_arg->db_charset)
 
1297
    charset_database_number= thd_arg->variables.collation_database->number;
 
1298
  
1283
1299
  /*
1284
1300
    If we don't use flags2 for anything else than options contained in
1285
1301
    thd->options, it would be more efficient to flags2=thd_arg->options
1350
1366
   db(NullS), catalog_len(0), status_vars_len(0),
1351
1367
   flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1352
1368
   auto_increment_increment(1), auto_increment_offset(1),
1353
 
   time_zone_len(0), lc_time_names_number(0)
 
1369
   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1354
1370
{
1355
1371
  ulong data_len;
1356
1372
  uint32 tmp;
1455
1471
      lc_time_names_number= uint2korr(pos);
1456
1472
      pos+= 2;
1457
1473
      break;
 
1474
    case Q_CHARSET_DATABASE_CODE:
 
1475
      charset_database_number= uint2korr(pos);
 
1476
      pos+= 2;
 
1477
      break;
1458
1478
    default:
1459
1479
      /* That's why you must write status vars in growing order of code */
1460
1480
      DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
1652
1672
            lc_time_names_number, print_event_info->delimiter);
1653
1673
    print_event_info->lc_time_names_number= lc_time_names_number;
1654
1674
  }
 
1675
  if (charset_database_number != print_event_info->charset_database_number)
 
1676
  {
 
1677
    if (charset_database_number)
 
1678
      fprintf(file, "SET @@session.collation_database=%d%s\n",
 
1679
              charset_database_number, print_event_info->delimiter);
 
1680
    else
 
1681
      fprintf(file, "SET @@session.collation_database=DEFAULT%s\n",
 
1682
              print_event_info->delimiter);
 
1683
    print_event_info->charset_database_number= charset_database_number;
 
1684
  }
1655
1685
}
1656
1686
 
1657
1687
 
1817
1847
      }
1818
1848
      else
1819
1849
        thd->variables.lc_time_names= &my_locale_en_US;
1820
 
 
 
1850
      if (charset_database_number)
 
1851
      {
 
1852
        CHARSET_INFO *cs;
 
1853
        if (!(cs= get_charset(charset_database_number, MYF(0))))
 
1854
        {
 
1855
          char buf[20];
 
1856
          int10_to_str((int) charset_database_number, buf, -10);
 
1857
          my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
 
1858
          goto compare_errors;
 
1859
        }
 
1860
        thd->variables.collation_database= cs;
 
1861
      }
 
1862
      else
 
1863
        thd->variables.collation_database= thd->db_charset;
 
1864
      
1821
1865
      /* Execute the query (note that we bypass dispatch_command()) */
1822
1866
      mysql_parse(thd, thd->query, thd->query_length);
1823
1867
 
2047
2091
  binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
2048
2092
  memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
2049
2093
         ST_SERVER_VER_LEN);
 
2094
  // prevent overrun if log is corrupted on disk
 
2095
  server_version[ST_SERVER_VER_LEN-1]= 0;
2050
2096
  created= uint4korr(buf+ST_CREATED_OFFSET);
2051
2097
  /* We use log_pos to mark if this was an artificial event or not */
2052
2098
  artificial_event= (log_pos == 0);
2170
2216
  switch (binlog_ver) {
2171
2217
  case 4: /* MySQL 5.0 */
2172
2218
    memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
 
2219
    DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
 
2220
                    strmov(server_version, "5.0.34"););
2173
2221
    common_header_len= LOG_EVENT_HEADER_LEN;
2174
2222
    number_of_event_types= LOG_EVENT_TYPES;
2175
2223
    /* we'll catch my_malloc() error in is_valid() */
2241
2289
    post_header_len= 0; /* will make is_valid() fail */
2242
2290
    break;
2243
2291
  }
 
2292
  calc_server_version_split();
2244
2293
}
2245
2294
 
2246
2295
 
2280
2329
  post_header_len= (uint8*) my_memdup((byte*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2281
2330
                                      number_of_event_types*
2282
2331
                                      sizeof(*post_header_len), MYF(0));
 
2332
  calc_server_version_split();
2283
2333
  DBUG_VOID_RETURN;
2284
2334
}
2285
2335
 
2380
2430
}
2381
2431
#endif
2382
2432
 
 
2433
 
 
2434
/**
 
2435
   Splits the event's 'server_version' string into three numeric pieces stored
 
2436
   into 'server_version_split':
 
2437
   X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
 
2438
   X.Yabc -> {X,Y,0}
 
2439
   Xabc -> {X,0,0}
 
2440
   'server_version_split' is then used for lookups to find if the server which
 
2441
   created this event has some known bug.
 
2442
*/
 
2443
void Format_description_log_event::calc_server_version_split()
 
2444
{
 
2445
  char *p= server_version, *r;
 
2446
  ulong number;
 
2447
  for (uint i= 0; i<=2; i++)
 
2448
  {
 
2449
    number= strtoul(p, &r, 10);
 
2450
    server_version_split[i]= (uchar)number;
 
2451
    DBUG_ASSERT(number < 256); // fit in uchar
 
2452
    p= r;
 
2453
    DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
 
2454
    if (*r == '.')
 
2455
      p++; // skip the dot
 
2456
  }
 
2457
  DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
 
2458
                     " '%s' %d %d %d", server_version,
 
2459
                     server_version_split[0],
 
2460
                     server_version_split[1], server_version_split[2]));
 
2461
}
 
2462
 
 
2463
 
2383
2464
  /**************************************************************************
2384
2465
        Load_log_event methods
2385
2466
   General note about Load_log_event: the binlogging of LOAD DATA INFILE is
3033
3114
 
3034
3115
      ex.skip_lines = skip_lines;
3035
3116
      List<Item> field_list;
3036
 
      thd->main_lex.select_lex.context.resolve_in_table_list_only(&tables);
3037
 
      set_fields(tables.db, field_list, &thd->main_lex.select_lex.context);
 
3117
      thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
 
3118
      set_fields(tables.db, field_list, &thd->lex->select_lex.context);
3038
3119
      thd->variables.pseudo_thread_id= thread_id;
3039
 
      List<Item> set_fields;
3040
3120
      if (net)
3041
3121
      {
3042
3122
        // mysql_load will use thd->net to read the file
3047
3127
        thd->net.pkt_nr = net->pkt_nr;
3048
3128
      }
3049
3129
      /*
3050
 
        It is safe to use set_fields twice because we are not going to
 
3130
        It is safe to use tmp_list twice because we are not going to
3051
3131
        update it inside mysql_load().
3052
3132
      */
3053
 
      if (mysql_load(thd, &ex, &tables, field_list, set_fields, set_fields,
 
3133
      List<Item> tmp_list;
 
3134
      if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
3054
3135
                     handle_dup, ignore, net != 0))
3055
3136
        thd->query_error= 1;
3056
3137
      if (thd->cuted_fields)
4315
4396
  bzero((char*)&file, sizeof(file));
4316
4397
  fname_buf= strmov(proc_info, "Making temp file ");
4317
4398
  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
4318
 
  thd_proc_info(thd, proc_info);
 
4399
  thd->proc_info= proc_info;
4319
4400
  my_delete(fname_buf, MYF(0)); // old copy may exist already
4320
4401
  if ((fd= my_create(fname_buf, CREATE_MODE,
4321
4402
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4369
4450
    end_io_cache(&file);
4370
4451
  if (fd >= 0)
4371
4452
    my_close(fd, MYF(0));
4372
 
  thd_proc_info(thd, 0);
 
4453
  thd->proc_info= 0;
4373
4454
  return error ? 1 : Log_event::exec_event(rli);
4374
4455
}
4375
4456
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4489
4570
 
4490
4571
  fname= strmov(proc_info, "Making temp file ");
4491
4572
  slave_load_file_stem(fname, file_id, server_id, ".data");
4492
 
  thd_proc_info(thd, proc_info);
 
4573
  thd->proc_info= proc_info;
4493
4574
  if (get_create_or_append())
4494
4575
  {
4495
4576
    my_delete(fname, MYF(0)); // old copy may exist already
4523
4604
err:
4524
4605
  if (fd >= 0)
4525
4606
    my_close(fd, MYF(0));
4526
 
  thd_proc_info(thd, 0);
 
4607
  thd->proc_info= 0;
4527
4608
  DBUG_RETURN(error ? error : Log_event::exec_event(rli));
4528
4609
}
4529
4610
#endif