~ubuntu-branches/ubuntu/hardy/mysql-dfsg-5.0/hardy-updates

« back to all changes in this revision

Viewing changes to libmysqld/sp_head.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2007-04-02 16:10:53 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070402161053-zkil9hjq9k5p1uzv
Tags: 5.0.37-0ubuntu1
* New upstream bugfix release.
  - Fixes replication failure with auto-increment and on duplicate key
    update, a regression introduced into 5.0.24. (LP: #95821)
* debian/control: Set Ubuntu maintainer.
* debian/rules: Change comments from 'Debian etch' to 'Ubuntu 7.04'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
5
 
   the Free Software Foundation; either version 2 of the License, or
6
 
   (at your option) any later version.
 
5
   the Free Software Foundation; version 2 of the License.
7
6
 
8
7
   This program is distributed in the hope that it will be useful,
9
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
93
92
*/
94
93
 
95
94
static String *
96
 
sp_get_item_value(Item *item, String *str)
 
95
sp_get_item_value(THD *thd, Item *item, String *str)
97
96
{
98
97
  Item_result result_type= item->result_type();
99
98
 
113
112
      {
114
113
        char buf_holder[STRING_BUFFER_USUAL_SIZE];
115
114
        String buf(buf_holder, sizeof(buf_holder), result->charset());
 
115
        CHARSET_INFO *cs= thd->variables.character_set_client;
116
116
 
117
117
        /* We must reset length of the buffer, because of String specificity. */
118
118
        buf.length(0);
119
119
 
120
120
        buf.append('_');
121
121
        buf.append(result->charset()->csname);
122
 
        if (result->charset()->escape_with_backslash_is_dangerous)
 
122
        if (cs->escape_with_backslash_is_dangerous)
123
123
          buf.append(' ');
124
 
        append_query_string(result->charset(), result, &buf);
 
124
        append_query_string(cs, result, &buf);
125
125
        str->copy(buf);
126
126
 
127
127
        return str;
606
606
  DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s",
607
607
                      m_type, m_name.str, m_params.str, m_body.str));
608
608
 
609
 
#ifndef DBUG_OFF
610
 
  optimize();
611
 
  {
612
 
    String s;
613
 
    sp_instr *i;
614
 
    uint ip= 0;
615
 
    while ((i = get_instr(ip)))
616
 
    {
617
 
      char buf[8];
618
 
 
619
 
      sprintf(buf, "%4u: ", ip);
620
 
      s.append(buf);
621
 
      i->print(&s);
622
 
      s.append('\n');
623
 
      ip+= 1;
624
 
    }
625
 
    s.append('\0');
626
 
    DBUG_PRINT("info", ("Code %s\n%s", m_qname.str, s.ptr()));
627
 
  }
628
 
#endif
629
 
 
630
609
  if (m_type == TYPE_ENUM_FUNCTION)
631
610
    ret= sp_create_function(thd, this);
632
611
  else
865
844
 
866
845
      val= (*splocal)->this_item();
867
846
      DBUG_PRINT("info", ("print %p", val));
868
 
      str_value= sp_get_item_value(val, &str_value_holder);
 
847
      str_value= sp_get_item_value(thd, val, &str_value_holder);
869
848
      if (str_value)
870
849
        res|= qbuf.append(*str_value);
871
850
      else
1449
1428
  {
1450
1429
    binlog_buf.length(0);
1451
1430
    binlog_buf.append(STRING_WITH_LEN("SELECT "));
 
1431
    append_identifier(thd, &binlog_buf, m_db.str, m_db.length);
 
1432
    binlog_buf.append('.');
1452
1433
    append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
1453
1434
    binlog_buf.append('(');
1454
1435
    for (arg_no= 0; arg_no < argcount; arg_no++)
1459
1440
      if (arg_no)
1460
1441
        binlog_buf.append(',');
1461
1442
 
1462
 
      str_value= sp_get_item_value(nctx->get_item(arg_no),
 
1443
      str_value= sp_get_item_value(thd, nctx->get_item(arg_no),
1463
1444
                                   &str_value_holder);
1464
1445
 
1465
1446
      if (str_value)
2174
2155
  This is the main mark and move loop; it relies on the following methods
2175
2156
  in sp_instr and its subclasses:
2176
2157
 
2177
 
  opt_mark()           Mark instruction as reachable (will recurse for jumps)
 
2158
  opt_mark()           Mark instruction as reachable
2178
2159
  opt_shortcut_jump()  Shortcut jumps to the final destination;
2179
2160
                       used by opt_mark().
2180
2161
  opt_move()           Update moved instruction
2187
2168
  sp_instr *i;
2188
2169
  uint src, dst;
2189
2170
 
2190
 
  opt_mark(0);
 
2171
  opt_mark();
2191
2172
 
2192
2173
  bp.empty();
2193
2174
  src= dst= 0;
2221
2202
  bp.empty();
2222
2203
}
2223
2204
 
 
2205
void sp_head::add_mark_lead(uint ip, List<sp_instr> *leads)
 
2206
{
 
2207
  sp_instr *i= get_instr(ip);
 
2208
 
 
2209
  if (i && ! i->marked)
 
2210
    leads->push_front(i);
 
2211
}
 
2212
 
2224
2213
void
2225
 
sp_head::opt_mark(uint ip)
 
2214
sp_head::opt_mark()
2226
2215
{
 
2216
  uint ip;
2227
2217
  sp_instr *i;
2228
 
 
2229
 
  while ((i= get_instr(ip)) && !i->marked)
2230
 
    ip= i->opt_mark(this);
 
2218
  List<sp_instr> leads;
 
2219
 
 
2220
  /*
 
2221
    Forward flow analysis algorithm in the instruction graph:
 
2222
    - first, add the entry point in the graph (the first instruction) to the
 
2223
      'leads' list of paths to explore.
 
2224
    - while there are still leads to explore:
 
2225
      - pick one lead, and follow the path forward. Mark instruction reached.
 
2226
        Stop only if the end of the routine is reached, or the path converge
 
2227
        to code already explored (marked).
 
2228
      - while following a path, collect in the 'leads' list any fork to
 
2229
        another path (caused by conditional jumps instructions), so that these
 
2230
        paths can be explored as well.
 
2231
  */
 
2232
 
 
2233
  /* Add the entry point */
 
2234
  i= get_instr(0);
 
2235
  leads.push_front(i);
 
2236
 
 
2237
  /* For each path of code ... */
 
2238
  while (leads.elements != 0)
 
2239
  {
 
2240
    i= leads.pop();
 
2241
 
 
2242
    /* Mark the entire path, collecting new leads. */
 
2243
    while (i && ! i->marked)
 
2244
    {
 
2245
      ip= i->opt_mark(this, & leads);
 
2246
      i= get_instr(ip);
 
2247
    }
 
2248
  }
2231
2249
}
2232
2250
 
2233
2251
 
2372
2390
 
2373
2391
  m_lex->unit.cleanup();
2374
2392
 
2375
 
  thd->proc_info="closing tables";
 
2393
  thd_proc_info(thd, "closing tables");
2376
2394
  close_thread_tables(thd);
2377
 
  thd->proc_info= 0;
 
2395
  thd_proc_info(thd, 0);
2378
2396
 
2379
2397
  if (m_lex->query_tables_own_last)
2380
2398
  {
2620
2638
}
2621
2639
 
2622
2640
uint
2623
 
sp_instr_jump::opt_mark(sp_head *sp)
 
2641
sp_instr_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
2624
2642
{
2625
2643
  m_dest= opt_shortcut_jump(sp, this);
2626
2644
  if (m_dest != m_ip+1)         /* Jumping to following instruction? */
2714
2732
 
2715
2733
 
2716
2734
uint
2717
 
sp_instr_jump_if_not::opt_mark(sp_head *sp)
 
2735
sp_instr_jump_if_not::opt_mark(sp_head *sp, List<sp_instr> *leads)
2718
2736
{
2719
2737
  sp_instr *i;
2720
2738
 
2724
2742
    m_dest= i->opt_shortcut_jump(sp, this);
2725
2743
    m_optdest= sp->get_instr(m_dest);
2726
2744
  }
2727
 
  sp->opt_mark(m_dest);
 
2745
  sp->add_mark_lead(m_dest, leads);
2728
2746
  if ((i= sp->get_instr(m_cont_dest)))
2729
2747
  {
2730
2748
    m_cont_dest= i->opt_shortcut_jump(sp, this);
2731
2749
    m_cont_optdest= sp->get_instr(m_cont_dest);
2732
2750
  }
2733
 
  sp->opt_mark(m_cont_dest);
 
2751
  sp->add_mark_lead(m_cont_dest, leads);
2734
2752
  return m_ip+1;
2735
2753
}
2736
2754
 
2851
2869
 
2852
2870
 
2853
2871
uint
2854
 
sp_instr_hpush_jump::opt_mark(sp_head *sp)
 
2872
sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
2855
2873
{
2856
2874
  sp_instr *i;
2857
2875
 
2861
2879
    m_dest= i->opt_shortcut_jump(sp, this);
2862
2880
    m_optdest= sp->get_instr(m_dest);
2863
2881
  }
2864
 
  sp->opt_mark(m_dest);
 
2882
  sp->add_mark_lead(m_dest, leads);
2865
2883
  return m_ip+1;
2866
2884
}
2867
2885
 
2926
2944
 
2927
2945
 
2928
2946
uint
2929
 
sp_instr_hreturn::opt_mark(sp_head *sp)
 
2947
sp_instr_hreturn::opt_mark(sp_head *sp, List<sp_instr> *leads)
2930
2948
{
2931
2949
  if (m_dest)
2932
 
    return sp_instr_jump::opt_mark(sp);
2933
 
  else
2934
 
  {
2935
 
    marked= 1;
2936
 
    return UINT_MAX;
2937
 
  }
 
2950
    return sp_instr_jump::opt_mark(sp, leads);
 
2951
 
 
2952
  marked= 1;
 
2953
  return UINT_MAX;
2938
2954
}
2939
2955
 
2940
2956
 
3277
3293
}
3278
3294
 
3279
3295
uint
3280
 
sp_instr_set_case_expr::opt_mark(sp_head *sp)
 
3296
sp_instr_set_case_expr::opt_mark(sp_head *sp, List<sp_instr> *leads)
3281
3297
{
3282
3298
  sp_instr *i;
3283
3299
 
3287
3303
    m_cont_dest= i->opt_shortcut_jump(sp, this);
3288
3304
    m_cont_optdest= sp->get_instr(m_cont_dest);
3289
3305
  }
3290
 
  sp->opt_mark(m_cont_dest);
 
3306
  sp->add_mark_lead(m_cont_dest, leads);
3291
3307
  return m_ip+1;
3292
3308
}
3293
3309