~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Brian Aker
  • Date: 2009-01-17 00:52:59 UTC
  • Revision ID: brian@gir-3.local-20090117005259-goyecyq0tpi9irnb
Pass through on refactoring functions to clases.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#include <drizzled/item/float.h>
42
42
#include <drizzled/item/return_int.h>
43
43
#include <drizzled/item/empty_string.h>
 
44
#include <drizzled/show.h>
44
45
 
45
46
extern scheduler_functions thread_scheduler;
46
47
/*
730
731
  mysql_ha_cleanup(this);
731
732
  delete_dynamic(&user_var_events);
732
733
  hash_free(&user_vars);
733
 
  close_temporary_tables(this);
 
734
  close_temporary_tables();
734
735
  free((char*) variables.time_format);
735
736
  free((char*) variables.date_format);
736
737
  free((char*) variables.datetime_format);
2594
2595
 
2595
2596
  return;
2596
2597
}
 
2598
 
 
2599
 
 
2600
/**
 
2601
  return true if the table was created explicitly.
 
2602
*/
 
2603
inline bool is_user_table(Table * table)
 
2604
{
 
2605
  const char *name= table->s->table_name.str;
 
2606
  return strncmp(name, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH);
 
2607
}
 
2608
 
 
2609
/*
 
2610
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
 
2611
  creates one DROP TEMPORARY Table binlog event for each pseudo-thread
 
2612
*/
 
2613
 
 
2614
void Session::close_temporary_tables()
 
2615
{
 
2616
  Table *table;
 
2617
  Table *next= NULL;
 
2618
  Table *prev_table;
 
2619
  /* Assume session->options has OPTION_QUOTE_SHOW_CREATE */
 
2620
  bool was_quote_show= true;
 
2621
 
 
2622
  if (!temporary_tables)
 
2623
    return;
 
2624
 
 
2625
  if (!drizzle_bin_log.is_open() || true )
 
2626
  {
 
2627
    Table *tmp_next;
 
2628
    for (table= temporary_tables; table; table= tmp_next)
 
2629
    {
 
2630
      tmp_next= table->next;
 
2631
      close_temporary(table, 1, 1);
 
2632
    }
 
2633
    temporary_tables= 0;
 
2634
 
 
2635
    return;
 
2636
  }
 
2637
 
 
2638
  /* Better add "if exists", in case a RESET MASTER has been done */
 
2639
  const char stub[]= "DROP /*!40005 TEMPORARY */ Table IF EXISTS ";
 
2640
  uint32_t stub_len= sizeof(stub) - 1;
 
2641
  char buf[256];
 
2642
  String s_query= String(buf, sizeof(buf), system_charset_info);
 
2643
  bool found_user_tables= false;
 
2644
 
 
2645
  memcpy(buf, stub, stub_len);
 
2646
 
 
2647
  /*
 
2648
    Insertion sort of temp tables by pseudo_thread_id to build ordered list
 
2649
    of sublists of equal pseudo_thread_id
 
2650
  */
 
2651
 
 
2652
  for (prev_table= temporary_tables, table= prev_table->next;
 
2653
       table;
 
2654
       prev_table= table, table= table->next)
 
2655
  {
 
2656
    Table *prev_sorted /* same as for prev_table */, *sorted;
 
2657
    if (is_user_table(table))
 
2658
    {
 
2659
      if (!found_user_tables)
 
2660
        found_user_tables= true;
 
2661
      for (prev_sorted= NULL, sorted= temporary_tables; sorted != table;
 
2662
           prev_sorted= sorted, sorted= sorted->next)
 
2663
      {
 
2664
        if (!is_user_table(sorted) || sorted->tmpkeyval() > table->tmpkeyval())
 
2665
        {
 
2666
          /* move into the sorted part of the list from the unsorted */
 
2667
          prev_table->next= table->next;
 
2668
          table->next= sorted;
 
2669
          if (prev_sorted)
 
2670
          {
 
2671
            prev_sorted->next= table;
 
2672
          }
 
2673
          else
 
2674
          {
 
2675
            temporary_tables= table;
 
2676
          }
 
2677
          table= prev_table;
 
2678
          break;
 
2679
        }
 
2680
      }
 
2681
    }
 
2682
  }
 
2683
 
 
2684
  /* We always quote db,table names though it is slight overkill */
 
2685
  if (found_user_tables && !(was_quote_show= test(options & OPTION_QUOTE_SHOW_CREATE)))
 
2686
  {
 
2687
    options |= OPTION_QUOTE_SHOW_CREATE;
 
2688
  }
 
2689
 
 
2690
  /* scan sorted tmps to generate sequence of DROP */
 
2691
  for (table= temporary_tables; table; table= next)
 
2692
  {
 
2693
    if (is_user_table(table))
 
2694
    {
 
2695
      my_thread_id save_pseudo_thread_id= variables.pseudo_thread_id;
 
2696
      /* Set pseudo_thread_id to be that of the processed table */
 
2697
      variables.pseudo_thread_id= table->tmpkeyval();
 
2698
      /*
 
2699
        Loop forward through all tables within the sublist of
 
2700
        common pseudo_thread_id to create single DROP query.
 
2701
      */
 
2702
      for (s_query.length(stub_len);
 
2703
           table && is_user_table(table) &&
 
2704
             table->tmpkeyval() == variables.pseudo_thread_id;
 
2705
           table= next)
 
2706
      {
 
2707
        /*
 
2708
          We are going to add 4 ` around the db/table names and possible more
 
2709
          due to special characters in the names
 
2710
        */
 
2711
        append_identifier(this, &s_query, table->s->db.str, strlen(table->s->db.str));
 
2712
        s_query.append('.');
 
2713
        append_identifier(this, &s_query, table->s->table_name.str,
 
2714
                          strlen(table->s->table_name.str));
 
2715
        s_query.append(',');
 
2716
        next= table->next;
 
2717
        close_temporary(table, 1, 1);
 
2718
      }
 
2719
      clear_error();
 
2720
      Query_log_event qinfo(this, s_query.ptr(),
 
2721
                            s_query.length() - 1 /* to remove trailing ',' */,
 
2722
                            0, false);
 
2723
      /*
 
2724
        Imagine the thread had created a temp table, then was doing a
 
2725
        SELECT, and the SELECT was killed. Then it's not clever to
 
2726
        mark the statement above as "killed", because it's not really
 
2727
        a statement updating data, and there are 99.99% chances it
 
2728
        will succeed on slave.  If a real update (one updating a
 
2729
        persistent table) was killed on the master, then this real
 
2730
        update will be logged with error_code=killed, rightfully
 
2731
        causing the slave to stop.
 
2732
      */
 
2733
      qinfo.error_code= 0;
 
2734
      drizzle_bin_log.write(&qinfo);
 
2735
      variables.pseudo_thread_id= save_pseudo_thread_id;
 
2736
    }
 
2737
    else
 
2738
    {
 
2739
      next= table->next;
 
2740
      close_temporary(table, 1, 1);
 
2741
    }
 
2742
  }
 
2743
  if (!was_quote_show)
 
2744
    options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
 
2745
  temporary_tables= NULL;
 
2746
}