2601
return true if the table was created explicitly.
2603
inline bool is_user_table(Table * table)
2605
const char *name= table->s->table_name.str;
2606
return strncmp(name, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH);
2610
Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
2611
creates one DROP TEMPORARY Table binlog event for each pseudo-thread
2614
void Session::close_temporary_tables()
2619
/* Assume session->options has OPTION_QUOTE_SHOW_CREATE */
2620
bool was_quote_show= true;
2622
if (!temporary_tables)
2625
if (!drizzle_bin_log.is_open() || true )
2628
for (table= temporary_tables; table; table= tmp_next)
2630
tmp_next= table->next;
2631
close_temporary(table, 1, 1);
2633
temporary_tables= 0;
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;
2642
String s_query= String(buf, sizeof(buf), system_charset_info);
2643
bool found_user_tables= false;
2645
memcpy(buf, stub, stub_len);
2648
Insertion sort of temp tables by pseudo_thread_id to build ordered list
2649
of sublists of equal pseudo_thread_id
2652
for (prev_table= temporary_tables, table= prev_table->next;
2654
prev_table= table, table= table->next)
2656
Table *prev_sorted /* same as for prev_table */, *sorted;
2657
if (is_user_table(table))
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)
2664
if (!is_user_table(sorted) || sorted->tmpkeyval() > table->tmpkeyval())
2666
/* move into the sorted part of the list from the unsorted */
2667
prev_table->next= table->next;
2668
table->next= sorted;
2671
prev_sorted->next= table;
2675
temporary_tables= table;
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)))
2687
options |= OPTION_QUOTE_SHOW_CREATE;
2690
/* scan sorted tmps to generate sequence of DROP */
2691
for (table= temporary_tables; table; table= next)
2693
if (is_user_table(table))
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();
2699
Loop forward through all tables within the sublist of
2700
common pseudo_thread_id to create single DROP query.
2702
for (s_query.length(stub_len);
2703
table && is_user_table(table) &&
2704
table->tmpkeyval() == variables.pseudo_thread_id;
2708
We are going to add 4 ` around the db/table names and possible more
2709
due to special characters in the names
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(',');
2717
close_temporary(table, 1, 1);
2720
Query_log_event qinfo(this, s_query.ptr(),
2721
s_query.length() - 1 /* to remove trailing ',' */,
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.
2733
qinfo.error_code= 0;
2734
drizzle_bin_log.write(&qinfo);
2735
variables.pseudo_thread_id= save_pseudo_thread_id;
2740
close_temporary(table, 1, 1);
2743
if (!was_quote_show)
2744
options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
2745
temporary_tables= NULL;