~vlad-lesin/percona-server/mysql-5.0.33-original

« back to all changes in this revision

Viewing changes to sql/sp_head.cc

  • Committer: Vlad Lesin
  • Date: 2012-07-31 09:21:34 UTC
  • Revision ID: vladislav.lesin@percona.com-20120731092134-zfodx022b7992wsi
VirginĀ 5.0.33

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2002 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
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.
 
7
 
 
8
   This program is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
   GNU General Public License for more details.
 
12
 
 
13
   You should have received a copy of the GNU General Public License
 
14
   along with this program; if not, write to the Free Software
 
15
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
16
 
 
17
#include "mysql_priv.h"
 
18
#ifdef USE_PRAGMA_IMPLEMENTATION
 
19
#pragma implementation
 
20
#endif
 
21
#include "sp_head.h"
 
22
#include "sp.h"
 
23
#include "sp_pcontext.h"
 
24
#include "sp_rcontext.h"
 
25
#include "sp_cache.h"
 
26
 
 
27
/*
 
28
  Sufficient max length of printed destinations and frame offsets (all uints).
 
29
*/
 
30
#define SP_INSTR_UINT_MAXLEN  8
 
31
#define SP_STMT_PRINT_MAXLEN 40
 
32
 
 
33
 
 
34
#include <my_user.h>
 
35
 
 
36
Item_result
 
37
sp_map_result_type(enum enum_field_types type)
 
38
{
 
39
  switch (type) {
 
40
  case MYSQL_TYPE_TINY:
 
41
  case MYSQL_TYPE_SHORT:
 
42
  case MYSQL_TYPE_LONG:
 
43
  case MYSQL_TYPE_LONGLONG:
 
44
  case MYSQL_TYPE_INT24:
 
45
    return INT_RESULT;
 
46
  case MYSQL_TYPE_DECIMAL:
 
47
  case MYSQL_TYPE_NEWDECIMAL:
 
48
    return DECIMAL_RESULT;
 
49
  case MYSQL_TYPE_FLOAT:
 
50
  case MYSQL_TYPE_DOUBLE:
 
51
    return REAL_RESULT;
 
52
  default:
 
53
    return STRING_RESULT;
 
54
  }
 
55
}
 
56
 
 
57
 
 
58
Item::Type
 
59
sp_map_item_type(enum enum_field_types type)
 
60
{
 
61
  switch (type) {
 
62
  case MYSQL_TYPE_TINY:
 
63
  case MYSQL_TYPE_SHORT:
 
64
  case MYSQL_TYPE_LONG:
 
65
  case MYSQL_TYPE_LONGLONG:
 
66
  case MYSQL_TYPE_INT24:
 
67
    return Item::INT_ITEM;
 
68
  case MYSQL_TYPE_DECIMAL:
 
69
  case MYSQL_TYPE_NEWDECIMAL:
 
70
    return Item::DECIMAL_ITEM;
 
71
  case MYSQL_TYPE_FLOAT:
 
72
  case MYSQL_TYPE_DOUBLE:
 
73
    return Item::REAL_ITEM;
 
74
  default:
 
75
    return Item::STRING_ITEM;
 
76
  }
 
77
}
 
78
 
 
79
 
 
80
/*
 
81
  Return a string representation of the Item value.
 
82
 
 
83
  NOTE: If the item has a string result type, the string is escaped
 
84
  according to its character set.
 
85
 
 
86
  SYNOPSIS
 
87
    item    a pointer to the Item
 
88
    str     string buffer for representation of the value
 
89
 
 
90
  RETURN
 
91
    NULL  on error
 
92
    a pointer to valid a valid string on success
 
93
*/
 
94
 
 
95
static String *
 
96
sp_get_item_value(Item *item, String *str)
 
97
{
 
98
  Item_result result_type= item->result_type();
 
99
 
 
100
  switch (item->result_type()) {
 
101
  case REAL_RESULT:
 
102
  case INT_RESULT:
 
103
  case DECIMAL_RESULT:
 
104
    return item->val_str(str);
 
105
 
 
106
  case STRING_RESULT:
 
107
    {
 
108
      String *result= item->val_str(str);
 
109
      
 
110
      if (!result)
 
111
        return NULL;
 
112
      
 
113
      {
 
114
        char buf_holder[STRING_BUFFER_USUAL_SIZE];
 
115
        String buf(buf_holder, sizeof(buf_holder), result->charset());
 
116
 
 
117
        /* We must reset length of the buffer, because of String specificity. */
 
118
        buf.length(0);
 
119
 
 
120
        buf.append('_');
 
121
        buf.append(result->charset()->csname);
 
122
        if (result->charset()->escape_with_backslash_is_dangerous)
 
123
          buf.append(' ');
 
124
        append_query_string(result->charset(), result, &buf);
 
125
        str->copy(buf);
 
126
 
 
127
        return str;
 
128
      }
 
129
    }
 
130
 
 
131
  case ROW_RESULT:
 
132
  default:
 
133
    return NULL;
 
134
  }
 
135
}
 
136
 
 
137
 
 
138
/*
 
139
  SYNOPSIS
 
140
    sp_get_flags_for_command()
 
141
 
 
142
  DESCRIPTION
 
143
    Returns a combination of:
 
144
    * sp_head::MULTI_RESULTS: added if the 'cmd' is a command that might
 
145
      result in multiple result sets being sent back.
 
146
    * sp_head::CONTAINS_DYNAMIC_SQL: added if 'cmd' is one of PREPARE,
 
147
      EXECUTE, DEALLOCATE.
 
148
*/
 
149
 
 
150
uint
 
151
sp_get_flags_for_command(LEX *lex)
 
152
{
 
153
  uint flags;
 
154
 
 
155
  switch (lex->sql_command) {
 
156
  case SQLCOM_SELECT:
 
157
    if (lex->result)
 
158
    {
 
159
      flags= 0;                      /* This is a SELECT with INTO clause */
 
160
      break;
 
161
    }
 
162
    /* fallthrough */
 
163
  case SQLCOM_ANALYZE:
 
164
  case SQLCOM_OPTIMIZE:
 
165
  case SQLCOM_PRELOAD_KEYS:
 
166
  case SQLCOM_ASSIGN_TO_KEYCACHE:
 
167
  case SQLCOM_CHECKSUM:
 
168
  case SQLCOM_CHECK:
 
169
  case SQLCOM_HA_READ:
 
170
  case SQLCOM_SHOW_BINLOGS:
 
171
  case SQLCOM_SHOW_BINLOG_EVENTS:
 
172
  case SQLCOM_SHOW_CHARSETS:
 
173
  case SQLCOM_SHOW_COLLATIONS:
 
174
  case SQLCOM_SHOW_COLUMN_TYPES:
 
175
  case SQLCOM_SHOW_CREATE:
 
176
  case SQLCOM_SHOW_CREATE_DB:
 
177
  case SQLCOM_SHOW_CREATE_FUNC:
 
178
  case SQLCOM_SHOW_CREATE_PROC:
 
179
  case SQLCOM_SHOW_DATABASES:
 
180
  case SQLCOM_SHOW_ERRORS:
 
181
  case SQLCOM_SHOW_FIELDS:
 
182
  case SQLCOM_SHOW_GRANTS:
 
183
  case SQLCOM_SHOW_INNODB_STATUS:
 
184
  case SQLCOM_SHOW_KEYS:
 
185
  case SQLCOM_SHOW_LOGS:
 
186
  case SQLCOM_SHOW_MASTER_STAT:
 
187
  case SQLCOM_SHOW_MUTEX_STATUS:
 
188
  case SQLCOM_SHOW_NEW_MASTER:
 
189
  case SQLCOM_SHOW_OPEN_TABLES:
 
190
  case SQLCOM_SHOW_PRIVILEGES:
 
191
  case SQLCOM_SHOW_PROCESSLIST:
 
192
  case SQLCOM_SHOW_SLAVE_HOSTS:
 
193
  case SQLCOM_SHOW_SLAVE_STAT:
 
194
  case SQLCOM_SHOW_STATUS:
 
195
  case SQLCOM_SHOW_STATUS_FUNC:
 
196
  case SQLCOM_SHOW_STATUS_PROC:
 
197
  case SQLCOM_SHOW_STORAGE_ENGINES:
 
198
  case SQLCOM_SHOW_TABLES:
 
199
  case SQLCOM_SHOW_VARIABLES:
 
200
  case SQLCOM_SHOW_WARNS:
 
201
  case SQLCOM_SHOW_PROC_CODE:
 
202
  case SQLCOM_SHOW_FUNC_CODE:
 
203
  case SQLCOM_REPAIR:
 
204
  case SQLCOM_BACKUP_TABLE:
 
205
  case SQLCOM_RESTORE_TABLE:
 
206
    flags= sp_head::MULTI_RESULTS;
 
207
    break;
 
208
  /*
 
209
    EXECUTE statement may return a result set, but doesn't have to.
 
210
    We can't, however, know it in advance, and therefore must add
 
211
    this statement here. This is ok, as is equivalent to a result-set
 
212
    statement within an IF condition.
 
213
  */
 
214
  case SQLCOM_EXECUTE:
 
215
    flags= sp_head::MULTI_RESULTS | sp_head::CONTAINS_DYNAMIC_SQL;
 
216
    break;
 
217
  case SQLCOM_PREPARE:
 
218
  case SQLCOM_DEALLOCATE_PREPARE:
 
219
    flags= sp_head::CONTAINS_DYNAMIC_SQL;
 
220
    break;
 
221
  case SQLCOM_CREATE_TABLE:
 
222
    if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
223
      flags= 0;
 
224
    else
 
225
      flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
 
226
    break;
 
227
  case SQLCOM_DROP_TABLE:
 
228
    if (lex->drop_temporary)
 
229
      flags= 0;
 
230
    else
 
231
      flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
 
232
    break;
 
233
  case SQLCOM_FLUSH:
 
234
    flags= sp_head::HAS_SQLCOM_FLUSH;
 
235
    break;
 
236
  case SQLCOM_RESET:
 
237
    flags= sp_head::HAS_SQLCOM_RESET;
 
238
    break;
 
239
  case SQLCOM_CREATE_INDEX:
 
240
  case SQLCOM_CREATE_DB:
 
241
  case SQLCOM_CREATE_VIEW:
 
242
  case SQLCOM_CREATE_TRIGGER:
 
243
  case SQLCOM_CREATE_USER:
 
244
  case SQLCOM_ALTER_TABLE:
 
245
  case SQLCOM_BEGIN:
 
246
  case SQLCOM_RENAME_TABLE:
 
247
  case SQLCOM_RENAME_USER:
 
248
  case SQLCOM_DROP_INDEX:
 
249
  case SQLCOM_DROP_DB:
 
250
  case SQLCOM_DROP_USER:
 
251
  case SQLCOM_DROP_VIEW:
 
252
  case SQLCOM_DROP_TRIGGER:
 
253
  case SQLCOM_TRUNCATE:
 
254
  case SQLCOM_COMMIT:
 
255
  case SQLCOM_ROLLBACK:
 
256
  case SQLCOM_LOAD:
 
257
  case SQLCOM_LOAD_MASTER_DATA:
 
258
  case SQLCOM_LOCK_TABLES:
 
259
  case SQLCOM_CREATE_PROCEDURE:
 
260
  case SQLCOM_CREATE_SPFUNCTION:
 
261
  case SQLCOM_ALTER_PROCEDURE:
 
262
  case SQLCOM_ALTER_FUNCTION:
 
263
  case SQLCOM_DROP_PROCEDURE:
 
264
  case SQLCOM_DROP_FUNCTION:
 
265
    flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
 
266
    break;
 
267
  default:
 
268
    flags= 0;
 
269
    break;
 
270
  }
 
271
  return flags;
 
272
}
 
273
 
 
274
 
 
275
/*
 
276
  Prepare an Item for evaluation (call of fix_fields).
 
277
 
 
278
  SYNOPSIS
 
279
    sp_prepare_func_item()
 
280
    thd       thread handler
 
281
    it_addr   pointer on item refernce
 
282
 
 
283
  RETURN
 
284
    NULL  error
 
285
    prepared item
 
286
*/
 
287
 
 
288
Item *
 
289
sp_prepare_func_item(THD* thd, Item **it_addr)
 
290
{
 
291
  DBUG_ENTER("sp_prepare_func_item");
 
292
  it_addr= (*it_addr)->this_item_addr(thd, it_addr);
 
293
 
 
294
  if (!(*it_addr)->fixed &&
 
295
      ((*it_addr)->fix_fields(thd, it_addr) ||
 
296
       (*it_addr)->check_cols(1)))
 
297
  {
 
298
    DBUG_PRINT("info", ("fix_fields() failed"));
 
299
    DBUG_RETURN(NULL);
 
300
  }
 
301
  DBUG_RETURN(*it_addr);
 
302
}
 
303
 
 
304
 
 
305
/*
 
306
  Evaluate an expression and store the result in the field.
 
307
 
 
308
  SYNOPSIS
 
309
    sp_eval_expr()
 
310
      thd                   - current thread object
 
311
      expr_item             - the root item of the expression
 
312
      result_field          - the field to store the result
 
313
 
 
314
  RETURN VALUES
 
315
    FALSE  on success
 
316
    TRUE   on error
 
317
*/
 
318
 
 
319
bool
 
320
sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
 
321
{
 
322
  Item *expr_item;
 
323
 
 
324
  DBUG_ENTER("sp_eval_expr");
 
325
 
 
326
  if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
 
327
    DBUG_RETURN(TRUE);
 
328
 
 
329
  bool err_status= FALSE;
 
330
 
 
331
  /*
 
332
    Set THD flags to emit warnings/errors in case of overflow/type errors
 
333
    during saving the item into the field.
 
334
 
 
335
    Save original values and restore them after save.
 
336
  */
 
337
  
 
338
  enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
 
339
  bool save_abort_on_warning= thd->abort_on_warning;
 
340
  bool save_no_trans_update= thd->no_trans_update;
 
341
 
 
342
  thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
343
  thd->abort_on_warning=
 
344
    thd->variables.sql_mode &
 
345
    (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
 
346
  thd->no_trans_update= 0;
 
347
 
 
348
  /* Save the value in the field. Convert the value if needed. */
 
349
 
 
350
  expr_item->save_in_field(result_field, 0);
 
351
 
 
352
  thd->count_cuted_fields= save_count_cuted_fields;
 
353
  thd->abort_on_warning= save_abort_on_warning;
 
354
  thd->no_trans_update= save_no_trans_update;
 
355
 
 
356
  if (thd->net.report_error)
 
357
  {
 
358
    /* Return error status if something went wrong. */
 
359
    err_status= TRUE;
 
360
  }
 
361
 
 
362
  DBUG_RETURN(err_status);
 
363
}
 
364
 
 
365
 
 
366
/*
 
367
 *
 
368
 *  sp_name
 
369
 *
 
370
 */
 
371
 
 
372
void
 
373
sp_name::init_qname(THD *thd)
 
374
{
 
375
  m_sroutines_key.length=  m_db.length + m_name.length + 2;
 
376
  if (!(m_sroutines_key.str= thd->alloc(m_sroutines_key.length + 1)))
 
377
    return;
 
378
  m_qname.length= m_sroutines_key.length - 1;
 
379
  m_qname.str= m_sroutines_key.str + 1;
 
380
  sprintf(m_qname.str, "%.*s.%.*s",
 
381
          m_db.length, (m_db.length ? m_db.str : ""),
 
382
          m_name.length, m_name.str);
 
383
}
 
384
 
 
385
 
 
386
/*
 
387
  Check that the name 'ident' is ok. It's assumed to be an 'ident'
 
388
  from the parser, so we only have to check length and trailing spaces.
 
389
  The former is a standard requirement (and 'show status' assumes a
 
390
  non-empty name), the latter is a mysql:ism as trailing spaces are
 
391
  removed by get_field().
 
392
 
 
393
  RETURN
 
394
   TRUE  - bad name
 
395
   FALSE - name is ok
 
396
*/
 
397
 
 
398
bool
 
399
check_routine_name(LEX_STRING ident)
 
400
{
 
401
  return (!ident.str || !ident.str[0] || ident.str[ident.length-1] == ' ');
 
402
}
 
403
 
 
404
/* ------------------------------------------------------------------ */
 
405
 
 
406
 
 
407
/*
 
408
 *
 
409
 *  sp_head
 
410
 *
 
411
 */
 
412
 
 
413
void *
 
414
sp_head::operator new(size_t size)
 
415
{
 
416
  DBUG_ENTER("sp_head::operator new");
 
417
  MEM_ROOT own_root;
 
418
  sp_head *sp;
 
419
 
 
420
  init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
 
421
  sp= (sp_head *) alloc_root(&own_root, size);
 
422
  sp->main_mem_root= own_root;
 
423
  DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
 
424
  DBUG_RETURN(sp);
 
425
}
 
426
 
 
427
void 
 
428
sp_head::operator delete(void *ptr, size_t size)
 
429
{
 
430
  DBUG_ENTER("sp_head::operator delete");
 
431
  MEM_ROOT own_root;
 
432
  sp_head *sp= (sp_head *) ptr;
 
433
 
 
434
  /* Make a copy of main_mem_root as free_root will free the sp */
 
435
  own_root= sp->main_mem_root;
 
436
  DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx",
 
437
                      (ulong) &sp->mem_root, (ulong) &own_root));
 
438
  free_root(&own_root, MYF(0));
 
439
 
 
440
  DBUG_VOID_RETURN;
 
441
}
 
442
 
 
443
 
 
444
sp_head::sp_head()
 
445
  :Query_arena(&main_mem_root, INITIALIZED_FOR_SP),
 
446
   m_flags(0), m_recursion_level(0), m_next_cached_sp(0),
 
447
   m_cont_level(0)
 
448
{
 
449
  m_first_instance= this;
 
450
  m_first_free_instance= this;
 
451
  m_last_cached_sp= this;
 
452
 
 
453
  m_return_field_def.charset = NULL;
 
454
 
 
455
  extern byte *
 
456
    sp_table_key(const byte *ptr, uint *plen, my_bool first);
 
457
  DBUG_ENTER("sp_head::sp_head");
 
458
 
 
459
  m_backpatch.empty();
 
460
  m_cont_backpatch.empty();
 
461
  m_lex.empty();
 
462
  hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
 
463
  hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
 
464
  DBUG_VOID_RETURN;
 
465
}
 
466
 
 
467
 
 
468
void
 
469
sp_head::init(LEX *lex)
 
470
{
 
471
  DBUG_ENTER("sp_head::init");
 
472
 
 
473
  lex->spcont= m_pcont= new sp_pcontext(NULL);
 
474
 
 
475
  /*
 
476
    Altough trg_table_fields list is used only in triggers we init for all
 
477
    types of stored procedures to simplify reset_lex()/restore_lex() code.
 
478
  */
 
479
  lex->trg_table_fields.empty();
 
480
  my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8);
 
481
  m_param_begin= m_param_end= m_body_begin= 0;
 
482
  m_qname.str= m_db.str= m_name.str= m_params.str=
 
483
    m_body.str= m_defstr.str= 0;
 
484
  m_qname.length= m_db.length= m_name.length= m_params.length=
 
485
    m_body.length= m_defstr.length= 0;
 
486
  m_return_field_def.charset= NULL;
 
487
  DBUG_VOID_RETURN;
 
488
}
 
489
 
 
490
 
 
491
void
 
492
sp_head::init_sp_name(THD *thd, sp_name *spname)
 
493
{
 
494
  DBUG_ENTER("sp_head::init_sp_name");
 
495
 
 
496
  /* Must be initialized in the parser. */
 
497
 
 
498
  DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length);
 
499
 
 
500
  /* We have to copy strings to get them into the right memroot. */
 
501
 
 
502
  m_db.length= spname->m_db.length;
 
503
  m_db.str= strmake_root(thd->mem_root, spname->m_db.str, spname->m_db.length);
 
504
 
 
505
  m_name.length= spname->m_name.length;
 
506
  m_name.str= strmake_root(thd->mem_root, spname->m_name.str,
 
507
                           spname->m_name.length);
 
508
 
 
509
  if (spname->m_qname.length == 0)
 
510
    spname->init_qname(thd);
 
511
 
 
512
  m_qname.length= spname->m_qname.length;
 
513
  m_qname.str= strmake_root(thd->mem_root, spname->m_qname.str,
 
514
                            m_qname.length);
 
515
}
 
516
 
 
517
 
 
518
void
 
519
sp_head::init_strings(THD *thd, LEX *lex)
 
520
{
 
521
  DBUG_ENTER("sp_head::init_strings");
 
522
  uchar *endp;                  /* Used to trim the end */
 
523
  /* During parsing, we must use thd->mem_root */
 
524
  MEM_ROOT *root= thd->mem_root;
 
525
 
 
526
  if (m_param_begin && m_param_end)
 
527
  {
 
528
    m_params.length= m_param_end - m_param_begin;
 
529
    m_params.str= strmake_root(root,
 
530
                               (char *)m_param_begin, m_params.length);
 
531
  }
 
532
 
 
533
  /* If ptr has overrun end_of_query then end_of_query is the end */
 
534
  endp= (lex->ptr > lex->end_of_query ? lex->end_of_query : lex->ptr);
 
535
  /*
 
536
    Trim "garbage" at the end. This is sometimes needed with the
 
537
    "/ * ! VERSION... * /" wrapper in dump files.
 
538
  */
 
539
  endp= skip_rear_comments(m_body_begin, endp);
 
540
 
 
541
  m_body.length= endp - m_body_begin;
 
542
  m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length);
 
543
  m_defstr.length= endp - lex->buf;
 
544
  m_defstr.str= strmake_root(root, (char *)lex->buf, m_defstr.length);
 
545
  DBUG_VOID_RETURN;
 
546
}
 
547
 
 
548
 
 
549
static TYPELIB *
 
550
create_typelib(MEM_ROOT *mem_root, create_field *field_def, List<String> *src)
 
551
{
 
552
  TYPELIB *result= NULL;
 
553
  CHARSET_INFO *cs= field_def->charset;
 
554
  DBUG_ENTER("create_typelib");
 
555
  if (src->elements)
 
556
  {
 
557
    result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
 
558
    result->count= src->elements;
 
559
    result->name= "";
 
560
    if (!(result->type_names=(const char **)
 
561
          alloc_root(mem_root,(sizeof(char *)+sizeof(int))*(result->count+1))))
 
562
      DBUG_RETURN(0);
 
563
    result->type_lengths= (unsigned int *)(result->type_names + result->count+1);
 
564
    List_iterator<String> it(*src);
 
565
    String conv;
 
566
    for (uint i=0; i < result->count; i++)
 
567
    {
 
568
      uint32 dummy;
 
569
      uint length;
 
570
      String *tmp= it++;
 
571
 
 
572
      if (String::needs_conversion(tmp->length(), tmp->charset(),
 
573
                                   cs, &dummy))
 
574
      {
 
575
        uint cnv_errs;
 
576
        conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
 
577
 
 
578
        length= conv.length();
 
579
        result->type_names[i]= (char*) strmake_root(mem_root, conv.ptr(),
 
580
                                                    length);
 
581
      }
 
582
      else
 
583
      {
 
584
        length= tmp->length();
 
585
        result->type_names[i]= strmake_root(mem_root, tmp->ptr(), length);
 
586
      }
 
587
 
 
588
      // Strip trailing spaces.
 
589
      length= cs->cset->lengthsp(cs, result->type_names[i], length);
 
590
      result->type_lengths[i]= length;
 
591
      ((uchar *)result->type_names[i])[length]= '\0';
 
592
    }
 
593
    result->type_names[result->count]= 0;
 
594
    result->type_lengths[result->count]= 0;
 
595
  }
 
596
  DBUG_RETURN(result);
 
597
}
 
598
 
 
599
 
 
600
int
 
601
sp_head::create(THD *thd)
 
602
{
 
603
  DBUG_ENTER("sp_head::create");
 
604
  int ret;
 
605
 
 
606
  DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s",
 
607
                      m_type, m_name.str, m_params.str, m_body.str));
 
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
  if (m_type == TYPE_ENUM_FUNCTION)
 
631
    ret= sp_create_function(thd, this);
 
632
  else
 
633
    ret= sp_create_procedure(thd, this);
 
634
 
 
635
  DBUG_RETURN(ret);
 
636
}
 
637
 
 
638
sp_head::~sp_head()
 
639
{
 
640
  destroy();
 
641
  delete m_next_cached_sp;
 
642
  if (m_thd)
 
643
    restore_thd_mem_root(m_thd);
 
644
}
 
645
 
 
646
void
 
647
sp_head::destroy()
 
648
{
 
649
  sp_instr *i;
 
650
  LEX *lex;
 
651
  DBUG_ENTER("sp_head::destroy");
 
652
  DBUG_PRINT("info", ("name: %s", m_name.str));
 
653
 
 
654
  for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
 
655
    delete i;
 
656
  delete_dynamic(&m_instr);
 
657
  m_pcont->destroy();
 
658
  free_items();
 
659
 
 
660
  /*
 
661
    If we have non-empty LEX stack then we just came out of parser with
 
662
    error. Now we should delete all auxilary LEXes and restore original
 
663
    THD::lex (In this case sp_head::restore_thd_mem_root() was not called
 
664
    too, so m_thd points to the current thread context).
 
665
    It is safe to not update LEX::ptr because further query string parsing
 
666
    and execution will be stopped anyway.
 
667
  */
 
668
  DBUG_ASSERT(m_lex.is_empty() || m_thd);
 
669
  while ((lex= (LEX *)m_lex.pop()))
 
670
  {
 
671
    lex_end(m_thd->lex);
 
672
    delete m_thd->lex;
 
673
    m_thd->lex= lex;
 
674
  }
 
675
 
 
676
  hash_free(&m_sptabs);
 
677
  hash_free(&m_sroutines);
 
678
  DBUG_VOID_RETURN;
 
679
}
 
680
 
 
681
 
 
682
/*
 
683
  This is only used for result fields from functions (both during
 
684
  fix_length_and_dec() and evaluation).
 
685
*/
 
686
 
 
687
Field *
 
688
sp_head::create_result_field(uint field_max_length, const char *field_name,
 
689
                             TABLE *table)
 
690
{
 
691
  uint field_length;
 
692
  Field *field;
 
693
 
 
694
  DBUG_ENTER("sp_head::create_result_field");
 
695
 
 
696
  field_length= !m_return_field_def.length ?
 
697
                field_max_length : m_return_field_def.length;
 
698
 
 
699
  field= ::make_field((char*) 0,                    /* field ptr */
 
700
                      field_length,                 /* field [max] length */
 
701
                      (uchar*) "",                  /* null ptr */
 
702
                      0,                            /* null bit */
 
703
                      m_return_field_def.pack_flag,
 
704
                      m_return_field_def.sql_type,
 
705
                      m_return_field_def.charset,
 
706
                      m_return_field_def.geom_type,
 
707
                      Field::NONE,                  /* unreg check */
 
708
                      m_return_field_def.interval,
 
709
                      field_name ? field_name : (const char *) m_name.str,
 
710
                      table);
 
711
  
 
712
  DBUG_RETURN(field);
 
713
}
 
714
 
 
715
 
 
716
int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
 
717
{
 
718
  return (int)((*a)->pos_in_query - (*b)->pos_in_query);
 
719
}
 
720
 
 
721
 
 
722
/*
 
723
  StoredRoutinesBinlogging
 
724
  Top-down overview:
 
725
 
 
726
  1. Statements
 
727
 
 
728
  Statements that have is_update_query(stmt) == TRUE are written into the
 
729
  binary log verbatim.
 
730
  Examples:
 
731
    UPDATE tbl SET tbl.x = spfunc_w_side_effects()
 
732
    UPDATE tbl SET tbl.x=1 WHERE spfunc_w_side_effect_that_returns_false(tbl.y)
 
733
 
 
734
  Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not
 
735
  written into binary log. Instead we catch function calls the statement
 
736
  makes and write it into binary log separately (see #3).
 
737
 
 
738
  2. PROCEDURE calls
 
739
 
 
740
  CALL statements are not written into binary log. Instead
 
741
  * Any FUNCTION invocation (in SET, IF, WHILE, OPEN CURSOR and other SP
 
742
    instructions) is written into binlog separately.
 
743
 
 
744
  * Each statement executed in SP is binlogged separately, according to rules
 
745
    in #1, with the exception that we modify query string: we replace uses
 
746
    of SP local variables with NAME_CONST('spvar_name', <spvar-value>) calls.
 
747
    This substitution is done in subst_spvars().
 
748
 
 
749
  3. FUNCTION calls
 
750
  
 
751
  In sp_head::execute_function(), we check 
 
752
   * If this function invocation is done from a statement that is written
 
753
     into the binary log.
 
754
   * If there were any attempts to write events to the binary log during
 
755
     function execution (grep for start_union_events and stop_union_events)
 
756
 
 
757
   If the answers are No and Yes, we write the function call into the binary
 
758
   log as "SELECT spfunc(<param1value>, <param2value>, ...)".
 
759
  
 
760
  
 
761
  4. Miscellaneous issues.
 
762
  
 
763
  4.1 User variables. 
 
764
 
 
765
  When we call mysql_bin_log.write() for an SP statement, thd->user_var_events
 
766
  must hold set<{var_name, value}> pairs for all user variables used during 
 
767
  the statement execution.
 
768
  This set is produced by tracking user variable reads during statement
 
769
  execution. 
 
770
 
 
771
  Fo SPs, this has the following implications:
 
772
  1) thd->user_var_events may contain events from several SP statements and 
 
773
     needs to be valid after exection of these statements was finished. In 
 
774
     order to achieve that, we
 
775
     * Allocate user_var_events array elements on appropriate mem_root (grep
 
776
       for user_var_events_alloc).
 
777
     * Use is_query_in_union() to determine if user_var_event is created.
 
778
     
 
779
  2) We need to empty thd->user_var_events after we have wrote a function
 
780
     call. This is currently done by making 
 
781
     reset_dynamic(&thd->user_var_events);
 
782
     calls in several different places. (TODO cosider moving this into
 
783
     mysql_bin_log.write() function)
 
784
*/
 
785
 
 
786
 
 
787
/*
 
788
  Replace thd->query{_length} with a string that one can write to the binlog.
 
789
 
 
790
  SYNOPSIS
 
791
    subst_spvars()
 
792
      thd        Current thread. 
 
793
      instr      Instruction (we look for Item_splocal instances in
 
794
                 instr->free_list)
 
795
      query_str  Original query string
 
796
     
 
797
  DESCRIPTION
 
798
 
 
799
  The binlog-suitable string is produced by replacing references to SP local 
 
800
  variables with NAME_CONST('sp_var_name', value) calls.
 
801
 
 
802
  RETURN
 
803
    FALSE  on success
 
804
           thd->query{_length} either has been appropriately replaced or there
 
805
           is no need for replacements.
 
806
    TRUE   out of memory error.
 
807
*/
 
808
 
 
809
static bool
 
810
subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
 
811
{
 
812
  DBUG_ENTER("subst_spvars");
 
813
  if (thd->prelocked_mode == NON_PRELOCKED && mysql_bin_log.is_open())
 
814
  {
 
815
    Dynamic_array<Item_splocal*> sp_vars_uses;
 
816
    char *pbuf, *cur, buffer[512];
 
817
    String qbuf(buffer, sizeof(buffer), &my_charset_bin);
 
818
    int prev_pos, res;
 
819
 
 
820
    /* Find all instances of Item_splocal used in this statement */
 
821
    for (Item *item= instr->free_list; item; item= item->next)
 
822
    {
 
823
      if (item->is_splocal())
 
824
      {
 
825
        Item_splocal *item_spl= (Item_splocal*)item;
 
826
        if (item_spl->pos_in_query)
 
827
          sp_vars_uses.append(item_spl);
 
828
      }
 
829
    }
 
830
    if (!sp_vars_uses.elements())
 
831
      DBUG_RETURN(FALSE);
 
832
      
 
833
    /* Sort SP var refs by their occurences in the query */
 
834
    sp_vars_uses.sort(cmp_splocal_locations);
 
835
 
 
836
    /* 
 
837
      Construct a statement string where SP local var refs are replaced
 
838
      with "NAME_CONST(name, value)"
 
839
    */
 
840
    qbuf.length(0);
 
841
    cur= query_str->str;
 
842
    prev_pos= res= 0;
 
843
    for (Item_splocal **splocal= sp_vars_uses.front(); 
 
844
         splocal < sp_vars_uses.back(); splocal++)
 
845
    {
 
846
      Item *val;
 
847
 
 
848
      char str_buffer[STRING_BUFFER_USUAL_SIZE];
 
849
      String str_value_holder(str_buffer, sizeof(str_buffer),
 
850
                              &my_charset_latin1);
 
851
      String *str_value;
 
852
      
 
853
      /* append the text between sp ref occurences */
 
854
      res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos);
 
855
      prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length;
 
856
      
 
857
      /* append the spvar substitute */
 
858
      res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('"));
 
859
      res|= qbuf.append((*splocal)->m_name.str, (*splocal)->m_name.length);
 
860
      res|= qbuf.append(STRING_WITH_LEN("',"));
 
861
      res|= (*splocal)->fix_fields(thd, (Item **) splocal);
 
862
 
 
863
      if (res)
 
864
        break;
 
865
 
 
866
      val= (*splocal)->this_item();
 
867
      DBUG_PRINT("info", ("print %p", val));
 
868
      str_value= sp_get_item_value(val, &str_value_holder);
 
869
      if (str_value)
 
870
        res|= qbuf.append(*str_value);
 
871
      else
 
872
        res|= qbuf.append(STRING_WITH_LEN("NULL"));
 
873
      res|= qbuf.append(')');
 
874
      if (res)
 
875
        break;
 
876
    }
 
877
    res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos);
 
878
    if (res)
 
879
      DBUG_RETURN(TRUE);
 
880
 
 
881
    if (!(pbuf= thd->strmake(qbuf.ptr(), qbuf.length())))
 
882
      DBUG_RETURN(TRUE);
 
883
 
 
884
    thd->query= pbuf;
 
885
    thd->query_length= qbuf.length();
 
886
  }
 
887
  DBUG_RETURN(FALSE);
 
888
}
 
889
 
 
890
 
 
891
/*
 
892
  Return appropriate error about recursion limit reaching
 
893
 
 
894
  SYNOPSIS
 
895
    sp_head::recursion_level_error()
 
896
    thd         Thread handle
 
897
 
 
898
  NOTE
 
899
    For functions and triggers we return error about prohibited recursion.
 
900
    For stored procedures we return about reaching recursion limit.
 
901
*/
 
902
 
 
903
void sp_head::recursion_level_error(THD *thd)
 
904
{
 
905
  if (m_type == TYPE_ENUM_PROCEDURE)
 
906
  {
 
907
    my_error(ER_SP_RECURSION_LIMIT, MYF(0),
 
908
             thd->variables.max_sp_recursion_depth,
 
909
             m_name.str);
 
910
  }
 
911
  else
 
912
    my_error(ER_SP_NO_RECURSION, MYF(0));
 
913
}
 
914
 
 
915
 
 
916
/*
 
917
  Execute the routine. The main instruction jump loop is there 
 
918
  Assume the parameters already set.
 
919
  
 
920
  RETURN
 
921
    FALSE  on success
 
922
    TRUE   on error
 
923
 
 
924
*/
 
925
 
 
926
bool
 
927
sp_head::execute(THD *thd)
 
928
{
 
929
  DBUG_ENTER("sp_head::execute");
 
930
  char old_db_buf[NAME_LEN+1];
 
931
  LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
 
932
  bool dbchanged;
 
933
  sp_rcontext *ctx;
 
934
  bool err_status= FALSE;
 
935
  uint ip= 0;
 
936
  ulong save_sql_mode;
 
937
  bool save_abort_on_warning;
 
938
  Query_arena *old_arena;
 
939
  /* per-instruction arena */
 
940
  MEM_ROOT execute_mem_root;
 
941
  Query_arena execute_arena(&execute_mem_root, INITIALIZED_FOR_SP),
 
942
              backup_arena;
 
943
  query_id_t old_query_id;
 
944
  TABLE *old_derived_tables;
 
945
  LEX *old_lex;
 
946
  Item_change_list old_change_list;
 
947
  String old_packet;
 
948
 
 
949
  /* Use some extra margin for possible SP recursion and functions */
 
950
  if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (char*)&old_packet))
 
951
    DBUG_RETURN(TRUE);
 
952
 
 
953
  /* init per-instruction memroot */
 
954
  init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
 
955
 
 
956
  DBUG_ASSERT(!(m_flags & IS_INVOKED));
 
957
  m_flags|= IS_INVOKED;
 
958
  m_first_instance->m_first_free_instance= m_next_cached_sp;
 
959
  if (m_next_cached_sp)
 
960
  {
 
961
    DBUG_PRINT("info",
 
962
               ("first free for 0x%lx ++: 0x%lx->0x%lx  level: %lu  flags %x",
 
963
                (ulong)m_first_instance, (ulong) this,
 
964
                (ulong) m_next_cached_sp,
 
965
                m_next_cached_sp->m_recursion_level,
 
966
                m_next_cached_sp->m_flags));
 
967
  }
 
968
  /*
 
969
    Check that if there are not any instances after this one then
 
970
    pointer to the last instance points on this instance or if there are
 
971
    some instances after this one then recursion level of next instance
 
972
    greater then recursion level of current instance on 1
 
973
  */
 
974
  DBUG_ASSERT((m_next_cached_sp == 0 &&
 
975
               m_first_instance->m_last_cached_sp == this) ||
 
976
              (m_recursion_level + 1 == m_next_cached_sp->m_recursion_level));
 
977
 
 
978
  if (m_db.length &&
 
979
      (err_status= sp_use_new_db(thd, m_db, &old_db, 0, &dbchanged)))
 
980
    goto done;
 
981
 
 
982
  if ((ctx= thd->spcont))
 
983
    ctx->clear_handler();
 
984
  thd->query_error= 0;
 
985
  old_arena= thd->stmt_arena;
 
986
 
 
987
  /*
 
988
    We have to save/restore this info when we are changing call level to
 
989
    be able properly do close_thread_tables() in instructions.
 
990
  */
 
991
  old_query_id= thd->query_id;
 
992
  old_derived_tables= thd->derived_tables;
 
993
  thd->derived_tables= 0;
 
994
  save_sql_mode= thd->variables.sql_mode;
 
995
  thd->variables.sql_mode= m_sql_mode;
 
996
  save_abort_on_warning= thd->abort_on_warning;
 
997
  thd->abort_on_warning= 0;
 
998
 
 
999
  /*
 
1000
    It is also more efficient to save/restore current thd->lex once when
 
1001
    do it in each instruction
 
1002
  */
 
1003
  old_lex= thd->lex;
 
1004
  /*
 
1005
    We should also save Item tree change list to avoid rollback something
 
1006
    too early in the calling query.
 
1007
  */
 
1008
  old_change_list= thd->change_list;
 
1009
  thd->change_list.empty();
 
1010
  /*
 
1011
    Cursors will use thd->packet, so they may corrupt data which was prepared
 
1012
    for sending by upper level. OTOH cursors in the same routine can share this
 
1013
    buffer safely so let use use routine-local packet instead of having own
 
1014
    packet buffer for each cursor.
 
1015
 
 
1016
    It is probably safe to use same thd->convert_buff everywhere.
 
1017
  */
 
1018
  old_packet.swap(thd->packet);
 
1019
 
 
1020
  /*
 
1021
    Switch to per-instruction arena here. We can do it since we cleanup
 
1022
    arena after every instruction.
 
1023
  */
 
1024
  thd->set_n_backup_active_arena(&execute_arena, &backup_arena);
 
1025
 
 
1026
  /*
 
1027
    Save callers arena in order to store instruction results and out
 
1028
    parameters in it later during sp_eval_func_item()
 
1029
  */
 
1030
  thd->spcont->callers_arena= &backup_arena;
 
1031
 
 
1032
  do
 
1033
  {
 
1034
    sp_instr *i;
 
1035
    uint hip;                   // Handler ip
 
1036
 
 
1037
    i = get_instr(ip);  // Returns NULL when we're done.
 
1038
    if (i == NULL)
 
1039
      break;
 
1040
    DBUG_PRINT("execute", ("Instruction %u", ip));
 
1041
    /* Don't change NOW() in FUNCTION or TRIGGER */
 
1042
    if (!thd->in_sub_stmt)
 
1043
      thd->set_time();          // Make current_time() et al work
 
1044
    
 
1045
    /*
 
1046
      We have to set thd->stmt_arena before executing the instruction
 
1047
      to store in the instruction free_list all new items, created
 
1048
      during the first execution (for example expanding of '*' or the
 
1049
      items made during other permanent subquery transformations).
 
1050
    */
 
1051
    thd->stmt_arena= i;
 
1052
    
 
1053
    /* 
 
1054
      Will write this SP statement into binlog separately 
 
1055
      (TODO: consider changing the condition to "not inside event union")
 
1056
    */
 
1057
    if (thd->prelocked_mode == NON_PRELOCKED)
 
1058
      thd->user_var_events_alloc= thd->mem_root;
 
1059
    
 
1060
    err_status= i->execute(thd, &ip);
 
1061
 
 
1062
    /*
 
1063
      If this SP instruction have sent eof, it has caused no_send_error to be
 
1064
      set. Clear it back to allow the next instruction to send error. (multi-
 
1065
      statement execution code clears no_send_error between statements too)
 
1066
    */
 
1067
    thd->net.no_send_error= 0;
 
1068
    if (i->free_list)
 
1069
      cleanup_items(i->free_list);
 
1070
    
 
1071
    /* 
 
1072
      If we've set thd->user_var_events_alloc to mem_root of this SP
 
1073
      statement, clean all the events allocated in it.
 
1074
    */
 
1075
    if (thd->prelocked_mode == NON_PRELOCKED)
 
1076
    {
 
1077
      reset_dynamic(&thd->user_var_events);
 
1078
      thd->user_var_events_alloc= NULL;//DEBUG
 
1079
    }
 
1080
 
 
1081
    /* we should cleanup free_list and memroot, used by instruction */
 
1082
    thd->cleanup_after_query();
 
1083
    free_root(&execute_mem_root, MYF(0));    
 
1084
 
 
1085
    /*
 
1086
      Check if an exception has occurred and a handler has been found
 
1087
      Note: We have to check even if err_status == FALSE, since warnings (and
 
1088
      some errors) don't return a non-zero value. We also have to check even
 
1089
      if thd->killed != 0, since some errors return with this even when a
 
1090
      handler has been found (e.g. "bad data").
 
1091
    */
 
1092
    if (ctx)
 
1093
    {
 
1094
      uint hf;
 
1095
 
 
1096
      switch (ctx->found_handler(&hip, &hf)) {
 
1097
      case SP_HANDLER_NONE:
 
1098
        break;
 
1099
      case SP_HANDLER_CONTINUE:
 
1100
        thd->restore_active_arena(&execute_arena, &backup_arena);
 
1101
        thd->set_n_backup_active_arena(&execute_arena, &backup_arena);
 
1102
        ctx->push_hstack(ip);
 
1103
        // Fall through
 
1104
      default:
 
1105
        ip= hip;
 
1106
        err_status= FALSE;
 
1107
        ctx->clear_handler();
 
1108
        ctx->enter_handler(hip);
 
1109
        thd->clear_error();
 
1110
        thd->killed= THD::NOT_KILLED;
 
1111
        continue;
 
1112
      }
 
1113
    }
 
1114
  } while (!err_status && !thd->killed);
 
1115
 
 
1116
  thd->restore_active_arena(&execute_arena, &backup_arena);
 
1117
 
 
1118
  thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
 
1119
 
 
1120
  /* Restore all saved */
 
1121
  old_packet.swap(thd->packet);
 
1122
  DBUG_ASSERT(thd->change_list.is_empty());
 
1123
  thd->change_list= old_change_list;
 
1124
  /* To avoid wiping out thd->change_list on old_change_list destruction */
 
1125
  old_change_list.empty();
 
1126
  thd->lex= old_lex;
 
1127
  thd->query_id= old_query_id;
 
1128
  DBUG_ASSERT(!thd->derived_tables);
 
1129
  thd->derived_tables= old_derived_tables;
 
1130
  thd->variables.sql_mode= save_sql_mode;
 
1131
  thd->abort_on_warning= save_abort_on_warning;
 
1132
 
 
1133
  thd->stmt_arena= old_arena;
 
1134
  state= EXECUTED;
 
1135
 
 
1136
 done:
 
1137
  DBUG_PRINT("info", ("err_status: %d  killed: %d  query_error: %d",
 
1138
                      err_status, thd->killed, thd->query_error));
 
1139
 
 
1140
  if (thd->killed)
 
1141
    err_status= TRUE;
 
1142
  /*
 
1143
    If the DB has changed, the pointer has changed too, but the
 
1144
    original thd->db will then have been freed
 
1145
  */
 
1146
  if (dbchanged)
 
1147
  {
 
1148
    /*
 
1149
      No access check when changing back to where we came from.
 
1150
      (It would generate an error from mysql_change_db() when old_db=="")
 
1151
    */
 
1152
    if (! thd->killed)
 
1153
      err_status|= mysql_change_db(thd, old_db.str, 1);
 
1154
  }
 
1155
  m_flags&= ~IS_INVOKED;
 
1156
  DBUG_PRINT("info",
 
1157
             ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x",
 
1158
              (ulong) m_first_instance,
 
1159
              (ulong) m_first_instance->m_first_free_instance,
 
1160
              (ulong) this, m_recursion_level, m_flags));
 
1161
  /*
 
1162
    Check that we have one of following:
 
1163
 
 
1164
    1) there are not free instances which means that this instance is last
 
1165
    in the list of instances (pointer to the last instance point on it and
 
1166
    ther are not other instances after this one in the list)
 
1167
 
 
1168
    2) There are some free instances which mean that first free instance
 
1169
    should go just after this one and recursion level of that free instance
 
1170
    should be on 1 more then recursion level of this instance.
 
1171
  */
 
1172
  DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 &&
 
1173
               this == m_first_instance->m_last_cached_sp &&
 
1174
               m_next_cached_sp == 0) ||
 
1175
              (m_first_instance->m_first_free_instance != 0 &&
 
1176
               m_first_instance->m_first_free_instance == m_next_cached_sp &&
 
1177
               m_first_instance->m_first_free_instance->m_recursion_level ==
 
1178
               m_recursion_level + 1));
 
1179
  m_first_instance->m_first_free_instance= this;
 
1180
 
 
1181
  DBUG_RETURN(err_status);
 
1182
}
 
1183
 
 
1184
 
 
1185
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1186
/*
 
1187
  set_routine_security_ctx() changes routine security context, and
 
1188
  checks if there is an EXECUTE privilege in new context.  If there is
 
1189
  no EXECUTE privilege, it changes the context back and returns a
 
1190
  error.
 
1191
 
 
1192
  SYNOPSIS
 
1193
    set_routine_security_ctx()
 
1194
      thd         thread handle
 
1195
      sp          stored routine to change the context for
 
1196
      is_proc     TRUE is procedure, FALSE if function
 
1197
      save_ctx    pointer to an old security context
 
1198
   
 
1199
  RETURN
 
1200
    TRUE if there was a error, and the context wasn't changed.
 
1201
    FALSE if the context was changed.
 
1202
*/
 
1203
 
 
1204
bool
 
1205
set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
 
1206
                         Security_context **save_ctx)
 
1207
{
 
1208
  *save_ctx= 0;
 
1209
  if (sp_change_security_context(thd, sp, save_ctx))
 
1210
    return TRUE;
 
1211
 
 
1212
  /*
 
1213
    If we changed context to run as another user, we need to check the
 
1214
    access right for the new context again as someone may have revoked
 
1215
    the right to use the procedure from this user.
 
1216
 
 
1217
    TODO:
 
1218
      Cache if the definer has the right to use the object on the
 
1219
      first usage and only reset the cache if someone does a GRANT
 
1220
      statement that 'may' affect this.
 
1221
  */
 
1222
  if (*save_ctx &&
 
1223
      check_routine_access(thd, EXECUTE_ACL,
 
1224
                           sp->m_db.str, sp->m_name.str, is_proc, FALSE))
 
1225
  {
 
1226
    sp_restore_security_context(thd, *save_ctx);
 
1227
    *save_ctx= 0;
 
1228
    return TRUE;
 
1229
  }
 
1230
 
 
1231
  return FALSE;
 
1232
}
 
1233
#endif // ! NO_EMBEDDED_ACCESS_CHECKS
 
1234
 
 
1235
 
 
1236
/*
 
1237
  Execute a trigger:
 
1238
   - changes security context for triggers
 
1239
   - switch to new memroot
 
1240
   - call sp_head::execute
 
1241
   - restore old memroot
 
1242
   - restores security context
 
1243
 
 
1244
  SYNOPSIS
 
1245
    sp_head::execute_trigger()
 
1246
      thd               Thread handle
 
1247
      db                database name
 
1248
      table             table name
 
1249
      grant_info        GRANT_INFO structure to be filled with
 
1250
                        information about definer's privileges
 
1251
                        on subject table
 
1252
   
 
1253
  RETURN
 
1254
    FALSE  on success
 
1255
    TRUE   on error
 
1256
*/
 
1257
 
 
1258
bool
 
1259
sp_head::execute_trigger(THD *thd, const char *db, const char *table,
 
1260
                         GRANT_INFO *grant_info)
 
1261
{
 
1262
  sp_rcontext *octx = thd->spcont;
 
1263
  sp_rcontext *nctx = NULL;
 
1264
  bool err_status= FALSE;
 
1265
  MEM_ROOT call_mem_root;
 
1266
  Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
 
1267
  Query_arena backup_arena;
 
1268
 
 
1269
  DBUG_ENTER("sp_head::execute_trigger");
 
1270
  DBUG_PRINT("info", ("trigger %s", m_name.str));
 
1271
 
 
1272
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1273
  Security_context *save_ctx;
 
1274
  if (sp_change_security_context(thd, this, &save_ctx))
 
1275
    DBUG_RETURN(TRUE);
 
1276
 
 
1277
  /*
 
1278
    NOTE: TRIGGER_ACL should be used here.
 
1279
  */
 
1280
  if (check_global_access(thd, SUPER_ACL))
 
1281
  {
 
1282
    sp_restore_security_context(thd, save_ctx);
 
1283
    DBUG_RETURN(TRUE);
 
1284
  }
 
1285
 
 
1286
  /*
 
1287
    Fetch information about table-level privileges to GRANT_INFO
 
1288
    structure for subject table. Check of privileges that will use it
 
1289
    and information about column-level privileges will happen in
 
1290
    Item_trigger_field::fix_fields().
 
1291
  */
 
1292
  fill_effective_table_privileges(thd, grant_info, db, table);
 
1293
#endif // NO_EMBEDDED_ACCESS_CHECKS
 
1294
 
 
1295
  /*
 
1296
    Prepare arena and memroot for objects which lifetime is whole
 
1297
    duration of trigger call (sp_rcontext, it's tables and items,
 
1298
    sp_cursor and Item_cache holders for case expressions).  We can't
 
1299
    use caller's arena/memroot for those objects because in this case
 
1300
    some fixed amount of memory will be consumed for each trigger
 
1301
    invocation and so statements which involve lot of them will hog
 
1302
    memory.
 
1303
 
 
1304
    TODO: we should create sp_rcontext once per command and reuse it
 
1305
    on subsequent executions of a trigger.
 
1306
  */
 
1307
  init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
 
1308
  thd->set_n_backup_active_arena(&call_arena, &backup_arena);
 
1309
 
 
1310
  if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) ||
 
1311
      nctx->init(thd))
 
1312
  {
 
1313
    err_status= TRUE;
 
1314
    goto err_with_cleanup;
 
1315
  }
 
1316
 
 
1317
#ifndef DBUG_OFF
 
1318
  nctx->sp= this;
 
1319
#endif
 
1320
 
 
1321
  thd->spcont= nctx;
 
1322
 
 
1323
  err_status= execute(thd);
 
1324
 
 
1325
err_with_cleanup:
 
1326
  thd->restore_active_arena(&call_arena, &backup_arena);
 
1327
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1328
  sp_restore_security_context(thd, save_ctx);
 
1329
#endif // NO_EMBEDDED_ACCESS_CHECKS
 
1330
  delete nctx;
 
1331
  call_arena.free_items();
 
1332
  free_root(&call_mem_root, MYF(0));
 
1333
  thd->spcont= octx;
 
1334
 
 
1335
  DBUG_RETURN(err_status);
 
1336
}
 
1337
 
 
1338
 
 
1339
/*
 
1340
  Execute a function:
 
1341
   - evaluate parameters
 
1342
   - changes security context for SUID routines
 
1343
   - switch to new memroot
 
1344
   - call sp_head::execute
 
1345
   - restore old memroot
 
1346
   - evaluate the return value
 
1347
   - restores security context
 
1348
 
 
1349
  SYNOPSIS
 
1350
    sp_head::execute_function()
 
1351
      thd               Thread handle
 
1352
      argp              Passed arguments (these are items from containing
 
1353
                        statement?)
 
1354
      argcount          Number of passed arguments. We need to check if this is
 
1355
                        correct.
 
1356
      return_value_fld  Save result here.
 
1357
   
 
1358
  RETURN
 
1359
    FALSE  on success
 
1360
    TRUE   on error
 
1361
*/
 
1362
 
 
1363
bool
 
1364
sp_head::execute_function(THD *thd, Item **argp, uint argcount,
 
1365
                          Field *return_value_fld)
 
1366
{
 
1367
  ulonglong binlog_save_options;
 
1368
  bool need_binlog_call;
 
1369
  uint arg_no;
 
1370
  sp_rcontext *octx = thd->spcont;
 
1371
  sp_rcontext *nctx = NULL;
 
1372
  char buf[STRING_BUFFER_USUAL_SIZE];
 
1373
  String binlog_buf(buf, sizeof(buf), &my_charset_bin);
 
1374
  bool err_status= FALSE;
 
1375
  MEM_ROOT call_mem_root;
 
1376
  Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
 
1377
  Query_arena backup_arena;
 
1378
 
 
1379
  DBUG_ENTER("sp_head::execute_function");
 
1380
  DBUG_PRINT("info", ("function %s", m_name.str));
 
1381
 
 
1382
  /*
 
1383
    Check that the function is called with all specified arguments.
 
1384
 
 
1385
    If it is not, use my_error() to report an error, or it will not terminate
 
1386
    the invoking query properly.
 
1387
  */
 
1388
  if (argcount != m_pcont->context_var_count())
 
1389
  {
 
1390
    /*
 
1391
      Need to use my_error here, or it will not terminate the
 
1392
      invoking query properly.
 
1393
    */
 
1394
    my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0),
 
1395
             "FUNCTION", m_qname.str, m_pcont->context_var_count(), argcount);
 
1396
    DBUG_RETURN(TRUE);
 
1397
  }
 
1398
  /*
 
1399
    Prepare arena and memroot for objects which lifetime is whole
 
1400
    duration of function call (sp_rcontext, it's tables and items,
 
1401
    sp_cursor and Item_cache holders for case expressions).
 
1402
    We can't use caller's arena/memroot for those objects because
 
1403
    in this case some fixed amount of memory will be consumed for
 
1404
    each function/trigger invocation and so statements which involve
 
1405
    lot of them will hog memory.
 
1406
    TODO: we should create sp_rcontext once per command and reuse
 
1407
    it on subsequent executions of a function/trigger.
 
1408
  */
 
1409
  init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
 
1410
  thd->set_n_backup_active_arena(&call_arena, &backup_arena);
 
1411
 
 
1412
  if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) ||
 
1413
      nctx->init(thd))
 
1414
  {
 
1415
    thd->restore_active_arena(&call_arena, &backup_arena);
 
1416
    err_status= TRUE;
 
1417
    goto err_with_cleanup;
 
1418
  }
 
1419
 
 
1420
  /*
 
1421
    We have to switch temporarily back to callers arena/memroot.
 
1422
    Function arguments belong to the caller and so the may reference
 
1423
    memory which they will allocate during calculation long after
 
1424
    this function call will be finished (e.g. in Item::cleanup()).
 
1425
  */
 
1426
  thd->restore_active_arena(&call_arena, &backup_arena);
 
1427
 
 
1428
#ifndef DBUG_OFF
 
1429
  nctx->sp= this;
 
1430
#endif
 
1431
 
 
1432
  /* Pass arguments. */
 
1433
  for (arg_no= 0; arg_no < argcount; arg_no++)
 
1434
  {
 
1435
    /* Arguments must be fixed in Item_func_sp::fix_fields */
 
1436
    DBUG_ASSERT(argp[arg_no]->fixed);
 
1437
 
 
1438
    if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no]))))
 
1439
      goto err_with_cleanup;
 
1440
  }
 
1441
 
 
1442
  need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
 
1443
 
 
1444
  /*
 
1445
    Remember the original arguments for unrolled replication of functions
 
1446
    before they are changed by execution.
 
1447
  */
 
1448
  if (need_binlog_call)
 
1449
  {
 
1450
    binlog_buf.length(0);
 
1451
    binlog_buf.append(STRING_WITH_LEN("SELECT "));
 
1452
    append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
 
1453
    binlog_buf.append('(');
 
1454
    for (arg_no= 0; arg_no < argcount; arg_no++)
 
1455
    {
 
1456
      String str_value_holder;
 
1457
      String *str_value;
 
1458
 
 
1459
      if (arg_no)
 
1460
        binlog_buf.append(',');
 
1461
 
 
1462
      str_value= sp_get_item_value(nctx->get_item(arg_no),
 
1463
                                   &str_value_holder);
 
1464
 
 
1465
      if (str_value)
 
1466
        binlog_buf.append(*str_value);
 
1467
      else
 
1468
        binlog_buf.append(STRING_WITH_LEN("NULL"));
 
1469
    }
 
1470
    binlog_buf.append(')');
 
1471
  }
 
1472
  thd->spcont= nctx;
 
1473
 
 
1474
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1475
  Security_context *save_security_ctx;
 
1476
  if (set_routine_security_ctx(thd, this, FALSE, &save_security_ctx))
 
1477
  {
 
1478
    err_status= TRUE;
 
1479
    goto err_with_cleanup;
 
1480
  }
 
1481
#endif
 
1482
 
 
1483
  binlog_save_options= thd->options;
 
1484
  if (need_binlog_call)
 
1485
  {
 
1486
    reset_dynamic(&thd->user_var_events);
 
1487
    mysql_bin_log.start_union_events(thd);
 
1488
  }
 
1489
 
 
1490
  /*
 
1491
    Switch to call arena/mem_root so objects like sp_cursor or
 
1492
    Item_cache holders for case expressions can be allocated on it.
 
1493
 
 
1494
    TODO: In future we should associate call arena/mem_root with
 
1495
          sp_rcontext and allocate all these objects (and sp_rcontext
 
1496
          itself) on it directly rather than juggle with arenas.
 
1497
  */
 
1498
  thd->set_n_backup_active_arena(&call_arena, &backup_arena);
 
1499
 
 
1500
  thd->options&= ~OPTION_BIN_LOG;
 
1501
  err_status= execute(thd);
 
1502
  thd->options= binlog_save_options;
 
1503
 
 
1504
  thd->restore_active_arena(&call_arena, &backup_arena);
 
1505
 
 
1506
  if (need_binlog_call)
 
1507
    mysql_bin_log.stop_union_events(thd);
 
1508
 
 
1509
  if (need_binlog_call && thd->binlog_evt_union.unioned_events)
 
1510
  {
 
1511
    Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
 
1512
                          thd->binlog_evt_union.unioned_events_trans, FALSE);
 
1513
    if (mysql_bin_log.write(&qinfo) &&
 
1514
        thd->binlog_evt_union.unioned_events_trans)
 
1515
    {
 
1516
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
1517
                   "Invoked ROUTINE modified a transactional table but MySQL "
 
1518
                   "failed to reflect this change in the binary log");
 
1519
    }
 
1520
    reset_dynamic(&thd->user_var_events);
 
1521
  }
 
1522
 
 
1523
  if (!err_status)
 
1524
  {
 
1525
    /* We need result only in function but not in trigger */
 
1526
 
 
1527
    if (!nctx->is_return_value_set())
 
1528
    {
 
1529
      my_error(ER_SP_NORETURNEND, MYF(0), m_name.str);
 
1530
      err_status= TRUE;
 
1531
    }
 
1532
  }
 
1533
 
 
1534
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1535
  sp_restore_security_context(thd, save_security_ctx);
 
1536
#endif
 
1537
 
 
1538
err_with_cleanup:
 
1539
  delete nctx;
 
1540
  call_arena.free_items();
 
1541
  free_root(&call_mem_root, MYF(0));
 
1542
  thd->spcont= octx;
 
1543
 
 
1544
  DBUG_RETURN(err_status);
 
1545
}
 
1546
 
 
1547
 
 
1548
/*
 
1549
  Execute a procedure. 
 
1550
  SYNOPSIS
 
1551
    sp_head::execute_procedure()
 
1552
      thd    Thread handle
 
1553
      args   List of values passed as arguments.
 
1554
      
 
1555
  DESCRIPTION
 
1556
 
 
1557
  The function does the following steps:
 
1558
   - Set all parameters 
 
1559
   - changes security context for SUID routines
 
1560
   - call sp_head::execute
 
1561
   - copy back values of INOUT and OUT parameters
 
1562
   - restores security context
 
1563
 
 
1564
  RETURN
 
1565
    FALSE  on success
 
1566
    TRUE   on error
 
1567
*/
 
1568
 
 
1569
bool
 
1570
sp_head::execute_procedure(THD *thd, List<Item> *args)
 
1571
{
 
1572
  bool err_status= FALSE;
 
1573
  uint params = m_pcont->context_var_count();
 
1574
  sp_rcontext *save_spcont, *octx;
 
1575
  sp_rcontext *nctx = NULL;
 
1576
  DBUG_ENTER("sp_head::execute_procedure");
 
1577
  DBUG_PRINT("info", ("procedure %s", m_name.str));
 
1578
 
 
1579
  if (args->elements != params)
 
1580
  {
 
1581
    my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE",
 
1582
             m_qname.str, params, args->elements);
 
1583
    DBUG_RETURN(TRUE);
 
1584
  }
 
1585
 
 
1586
  save_spcont= octx= thd->spcont;
 
1587
  if (! octx)
 
1588
  {                             // Create a temporary old context
 
1589
    if (!(octx= new sp_rcontext(m_pcont, NULL, octx)) ||
 
1590
        octx->init(thd))
 
1591
    {
 
1592
      delete octx; /* Delete octx if it was init() that failed. */
 
1593
      DBUG_RETURN(TRUE);
 
1594
    }
 
1595
    
 
1596
#ifndef DBUG_OFF
 
1597
    octx->sp= 0;
 
1598
#endif
 
1599
    thd->spcont= octx;
 
1600
 
 
1601
    /* set callers_arena to thd, for upper-level function to work */
 
1602
    thd->spcont->callers_arena= thd;
 
1603
  }
 
1604
 
 
1605
  if (!(nctx= new sp_rcontext(m_pcont, NULL, octx)) ||
 
1606
      nctx->init(thd))
 
1607
  {
 
1608
    delete nctx; /* Delete nctx if it was init() that failed. */
 
1609
    thd->spcont= save_spcont;
 
1610
    DBUG_RETURN(TRUE);
 
1611
  }
 
1612
#ifndef DBUG_OFF
 
1613
  nctx->sp= this;
 
1614
#endif
 
1615
 
 
1616
  if (params > 0)
 
1617
  {
 
1618
    List_iterator<Item> it_args(*args);
 
1619
 
 
1620
    DBUG_PRINT("info",(" %.*s: eval args", m_name.length, m_name.str));
 
1621
 
 
1622
    for (uint i= 0 ; i < params ; i++)
 
1623
    {
 
1624
      Item *arg_item= it_args++;
 
1625
 
 
1626
      if (!arg_item)
 
1627
        break;
 
1628
 
 
1629
      sp_variable_t *spvar= m_pcont->find_variable(i);
 
1630
 
 
1631
      if (!spvar)
 
1632
        continue;
 
1633
 
 
1634
      if (spvar->mode != sp_param_in)
 
1635
      {
 
1636
        Settable_routine_parameter *srp=
 
1637
          arg_item->get_settable_routine_parameter();
 
1638
 
 
1639
        if (!srp)
 
1640
        {
 
1641
          my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, m_qname.str);
 
1642
          err_status= TRUE;
 
1643
          break;
 
1644
        }
 
1645
 
 
1646
        srp->set_required_privilege(spvar->mode == sp_param_inout);
 
1647
      }
 
1648
 
 
1649
      if (spvar->mode == sp_param_out)
 
1650
      {
 
1651
        Item_null *null_item= new Item_null();
 
1652
 
 
1653
        if (!null_item ||
 
1654
            nctx->set_variable(thd, i, (Item **)&null_item))
 
1655
        {
 
1656
          err_status= TRUE;
 
1657
          break;
 
1658
        }
 
1659
      }
 
1660
      else
 
1661
      {
 
1662
        if (nctx->set_variable(thd, i, it_args.ref()))
 
1663
        {
 
1664
          err_status= TRUE;
 
1665
          break;
 
1666
        }
 
1667
      }
 
1668
    }
 
1669
 
 
1670
    /* 
 
1671
      Okay, got values for all arguments. Close tables that might be used by 
 
1672
      arguments evaluation. If arguments evaluation required prelocking mode, 
 
1673
      we'll leave it here.
 
1674
    */
 
1675
    if (!thd->in_sub_stmt)
 
1676
      close_thread_tables(thd, 0, 0);
 
1677
 
 
1678
    DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str));
 
1679
  }
 
1680
 
 
1681
  thd->spcont= nctx;
 
1682
 
 
1683
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1684
  Security_context *save_security_ctx= 0;
 
1685
  if (!err_status)
 
1686
    err_status= set_routine_security_ctx(thd, this, TRUE, &save_security_ctx);
 
1687
#endif
 
1688
 
 
1689
  if (!err_status)
 
1690
    err_status= execute(thd);
 
1691
 
 
1692
  /*
 
1693
    In the case when we weren't able to employ reuse mechanism for
 
1694
    OUT/INOUT paranmeters, we should reallocate memory. This
 
1695
    allocation should be done on the arena which will live through
 
1696
    all execution of calling routine.
 
1697
  */
 
1698
  thd->spcont->callers_arena= octx->callers_arena;
 
1699
 
 
1700
  if (!err_status && params > 0)
 
1701
  {
 
1702
    List_iterator<Item> it_args(*args);
 
1703
 
 
1704
    /*
 
1705
      Copy back all OUT or INOUT values to the previous frame, or
 
1706
      set global user variables
 
1707
    */
 
1708
    for (uint i= 0 ; i < params ; i++)
 
1709
    {
 
1710
      Item *arg_item= it_args++;
 
1711
 
 
1712
      if (!arg_item)
 
1713
        break;
 
1714
 
 
1715
      sp_variable_t *spvar= m_pcont->find_variable(i);
 
1716
 
 
1717
      if (spvar->mode == sp_param_in)
 
1718
        continue;
 
1719
 
 
1720
      Settable_routine_parameter *srp=
 
1721
        arg_item->get_settable_routine_parameter();
 
1722
 
 
1723
      DBUG_ASSERT(srp);
 
1724
 
 
1725
      if (srp->set_value(thd, octx, nctx->get_item_addr(i)))
 
1726
      {
 
1727
        err_status= TRUE;
 
1728
        break;
 
1729
      }
 
1730
    }
 
1731
  }
 
1732
 
 
1733
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1734
  if (save_security_ctx)
 
1735
    sp_restore_security_context(thd, save_security_ctx);
 
1736
#endif
 
1737
 
 
1738
  if (!save_spcont)
 
1739
    delete octx;
 
1740
 
 
1741
  delete nctx;
 
1742
  thd->spcont= save_spcont;
 
1743
 
 
1744
  DBUG_RETURN(err_status);
 
1745
}
 
1746
 
 
1747
 
 
1748
// Reset lex during parsing, before we parse a sub statement.
 
1749
void
 
1750
sp_head::reset_lex(THD *thd)
 
1751
{
 
1752
  DBUG_ENTER("sp_head::reset_lex");
 
1753
  LEX *sublex;
 
1754
  LEX *oldlex= thd->lex;
 
1755
  my_lex_states state= oldlex->next_state; // Keep original next_state
 
1756
 
 
1757
  (void)m_lex.push_front(oldlex);
 
1758
  thd->lex= sublex= new st_lex;
 
1759
 
 
1760
  /* Reset most stuff. The length arguments doesn't matter here. */
 
1761
  lex_start(thd, oldlex->buf, (ulong) (oldlex->end_of_query - oldlex->ptr));
 
1762
 
 
1763
  /*
 
1764
   * next_state is normally the same (0), but it happens that we swap lex in
 
1765
   * "mid-sentence", so we must restore it.
 
1766
   */
 
1767
  sublex->next_state= state;
 
1768
  /* We must reset ptr and end_of_query again */
 
1769
  sublex->ptr= oldlex->ptr;
 
1770
  sublex->end_of_query= oldlex->end_of_query;
 
1771
  sublex->tok_start= oldlex->tok_start;
 
1772
  sublex->yylineno= oldlex->yylineno;
 
1773
  /* And keep the SP stuff too */
 
1774
  sublex->sphead= oldlex->sphead;
 
1775
  sublex->spcont= oldlex->spcont;
 
1776
  /* And trigger related stuff too */
 
1777
  sublex->trg_chistics= oldlex->trg_chistics;
 
1778
  sublex->trg_table_fields.empty();
 
1779
  sublex->sp_lex_in_use= FALSE;
 
1780
 
 
1781
  sublex->in_comment= oldlex->in_comment;
 
1782
 
 
1783
  /* Reset type info. */
 
1784
 
 
1785
  sublex->charset= NULL;
 
1786
  sublex->length= NULL;
 
1787
  sublex->dec= NULL;
 
1788
  sublex->interval_list.empty();
 
1789
  sublex->type= 0;
 
1790
 
 
1791
  DBUG_VOID_RETURN;
 
1792
}
 
1793
 
 
1794
// Restore lex during parsing, after we have parsed a sub statement.
 
1795
void
 
1796
sp_head::restore_lex(THD *thd)
 
1797
{
 
1798
  DBUG_ENTER("sp_head::restore_lex");
 
1799
  LEX *sublex= thd->lex;
 
1800
  LEX *oldlex= (LEX *)m_lex.pop();
 
1801
 
 
1802
  if (! oldlex)
 
1803
    return;                     // Nothing to restore
 
1804
 
 
1805
  // Update some state in the old one first
 
1806
  oldlex->ptr= sublex->ptr;
 
1807
  oldlex->next_state= sublex->next_state;
 
1808
  oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
 
1809
 
 
1810
  /*
 
1811
    Add routines which are used by statement to respective set for
 
1812
    this routine.
 
1813
  */
 
1814
  sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines);
 
1815
  /*
 
1816
    Merge tables used by this statement (but not by its functions or
 
1817
    procedures) to multiset of tables used by this routine.
 
1818
  */
 
1819
  merge_table_list(thd, sublex->query_tables, sublex);
 
1820
  if (! sublex->sp_lex_in_use)
 
1821
  {
 
1822
    lex_end(sublex);
 
1823
    delete sublex;
 
1824
  }
 
1825
  thd->lex= oldlex;
 
1826
  DBUG_VOID_RETURN;
 
1827
}
 
1828
 
 
1829
void
 
1830
sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
 
1831
{
 
1832
  bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t));
 
1833
 
 
1834
  if (bp)
 
1835
  {
 
1836
    bp->lab= lab;
 
1837
    bp->instr= i;
 
1838
    (void)m_backpatch.push_front(bp);
 
1839
  }
 
1840
}
 
1841
 
 
1842
void
 
1843
sp_head::backpatch(sp_label_t *lab)
 
1844
{
 
1845
  bp_t *bp;
 
1846
  uint dest= instructions();
 
1847
  List_iterator_fast<bp_t> li(m_backpatch);
 
1848
 
 
1849
  while ((bp= li++))
 
1850
  {
 
1851
    if (bp->lab == lab)
 
1852
      bp->instr->backpatch(dest, lab->ctx);
 
1853
  }
 
1854
}
 
1855
 
 
1856
/*
 
1857
  Prepare an instance of create_field for field creation (fill all necessary
 
1858
  attributes).
 
1859
 
 
1860
  SYNOPSIS
 
1861
    sp_head::fill_field_definition()
 
1862
      thd         [IN] Thread handle
 
1863
      lex         [IN] Yacc parsing context
 
1864
      field_type  [IN] Field type
 
1865
      field_def   [OUT] An instance of create_field to be filled
 
1866
 
 
1867
  RETURN
 
1868
    FALSE  on success
 
1869
    TRUE   on error
 
1870
*/
 
1871
 
 
1872
bool
 
1873
sp_head::fill_field_definition(THD *thd, LEX *lex,
 
1874
                               enum enum_field_types field_type,
 
1875
                               create_field *field_def)
 
1876
{
 
1877
  HA_CREATE_INFO sp_db_info;
 
1878
  LEX_STRING cmt = { 0, 0 };
 
1879
  uint unused1= 0;
 
1880
  int unused2= 0;
 
1881
 
 
1882
  load_db_opt_by_name(thd, m_db.str, &sp_db_info);
 
1883
 
 
1884
  if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
 
1885
                      lex->type, (Item*) 0, (Item*) 0, &cmt, 0,
 
1886
                      &lex->interval_list,
 
1887
                      (lex->charset ? lex->charset :
 
1888
                                      sp_db_info.default_table_charset),
 
1889
                      lex->uint_geom_type))
 
1890
    return TRUE;
 
1891
 
 
1892
  if (field_def->interval_list.elements)
 
1893
    field_def->interval= create_typelib(mem_root, field_def,
 
1894
                                        &field_def->interval_list);
 
1895
 
 
1896
  sp_prepare_create_field(thd, field_def);
 
1897
 
 
1898
  if (prepare_create_field(field_def, &unused1, &unused2, &unused2,
 
1899
                           HA_CAN_GEOMETRY))
 
1900
  {
 
1901
    return TRUE;
 
1902
  }
 
1903
 
 
1904
  return FALSE;
 
1905
}
 
1906
 
 
1907
 
 
1908
void
 
1909
sp_head::new_cont_backpatch(sp_instr_opt_meta *i)
 
1910
{
 
1911
  m_cont_level+= 1;
 
1912
  if (i)
 
1913
  {
 
1914
    /* Use the cont. destination slot to store the level */
 
1915
    i->m_cont_dest= m_cont_level;
 
1916
    (void)m_cont_backpatch.push_front(i);
 
1917
  }
 
1918
}
 
1919
 
 
1920
void
 
1921
sp_head::add_cont_backpatch(sp_instr_opt_meta *i)
 
1922
{
 
1923
  i->m_cont_dest= m_cont_level;
 
1924
  (void)m_cont_backpatch.push_front(i);
 
1925
}
 
1926
 
 
1927
void
 
1928
sp_head::do_cont_backpatch()
 
1929
{
 
1930
  uint dest= instructions();
 
1931
  uint lev= m_cont_level--;
 
1932
  sp_instr_opt_meta *i;
 
1933
 
 
1934
  while ((i= m_cont_backpatch.head()) && i->m_cont_dest == lev)
 
1935
  {
 
1936
    i->m_cont_dest= dest;
 
1937
    (void)m_cont_backpatch.pop();
 
1938
  }
 
1939
}
 
1940
 
 
1941
void
 
1942
sp_head::set_info(longlong created, longlong modified,
 
1943
                  st_sp_chistics *chistics, ulong sql_mode)
 
1944
{
 
1945
  m_created= created;
 
1946
  m_modified= modified;
 
1947
  m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics,
 
1948
                                             sizeof(*chistics));
 
1949
  if (m_chistics->comment.length == 0)
 
1950
    m_chistics->comment.str= 0;
 
1951
  else
 
1952
    m_chistics->comment.str= strmake_root(mem_root,
 
1953
                                          m_chistics->comment.str,
 
1954
                                          m_chistics->comment.length);
 
1955
  m_sql_mode= sql_mode;
 
1956
}
 
1957
 
 
1958
 
 
1959
void
 
1960
sp_head::set_definer(const char *definer, uint definerlen)
 
1961
{
 
1962
  char user_name_holder[USERNAME_LENGTH + 1];
 
1963
  LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_LENGTH);
 
1964
 
 
1965
  char host_name_holder[HOSTNAME_LENGTH + 1];
 
1966
  LEX_STRING_WITH_INIT host_name(host_name_holder, HOSTNAME_LENGTH);
 
1967
 
 
1968
  parse_user(definer, definerlen, user_name.str, &user_name.length,
 
1969
             host_name.str, &host_name.length);
 
1970
 
 
1971
  set_definer(&user_name, &host_name);
 
1972
}
 
1973
 
 
1974
 
 
1975
void
 
1976
sp_head::set_definer(const LEX_STRING *user_name, const LEX_STRING *host_name)
 
1977
{
 
1978
  m_definer_user.str= strmake_root(mem_root, user_name->str, user_name->length);
 
1979
  m_definer_user.length= user_name->length;
 
1980
 
 
1981
  m_definer_host.str= strmake_root(mem_root, host_name->str, host_name->length);
 
1982
  m_definer_host.length= host_name->length;
 
1983
}
 
1984
 
 
1985
 
 
1986
void
 
1987
sp_head::reset_thd_mem_root(THD *thd)
 
1988
{
 
1989
  DBUG_ENTER("sp_head::reset_thd_mem_root");
 
1990
  m_thd_root= thd->mem_root;
 
1991
  thd->mem_root= &main_mem_root;
 
1992
  DBUG_PRINT("info", ("mem_root 0x%lx moved to thd mem root 0x%lx",
 
1993
                      (ulong) &mem_root, (ulong) &thd->mem_root));
 
1994
  free_list= thd->free_list; // Keep the old list
 
1995
  thd->free_list= NULL; // Start a new one
 
1996
  m_thd= thd;
 
1997
  DBUG_VOID_RETURN;
 
1998
}
 
1999
 
 
2000
void
 
2001
sp_head::restore_thd_mem_root(THD *thd)
 
2002
{
 
2003
  DBUG_ENTER("sp_head::restore_thd_mem_root");
 
2004
  Item *flist= free_list;       // The old list
 
2005
  set_query_arena(thd);         // Get new free_list and mem_root
 
2006
  state= INITIALIZED_FOR_SP;
 
2007
 
 
2008
  DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx",
 
2009
                      (ulong) &mem_root, (ulong) &thd->mem_root));
 
2010
  thd->free_list= flist;        // Restore the old one
 
2011
  thd->mem_root= m_thd_root;
 
2012
  m_thd= NULL;
 
2013
  DBUG_VOID_RETURN;
 
2014
}
 
2015
 
 
2016
 
 
2017
/*
 
2018
  Check if a user has access right to a routine
 
2019
 
 
2020
  SYNOPSIS
 
2021
    check_show_routine_access()
 
2022
    thd                 Thread handler
 
2023
    sp                  SP
 
2024
    full_access         Set to 1 if the user has SELECT right to the
 
2025
                        'mysql.proc' able or is the owner of the routine
 
2026
  RETURN
 
2027
    0  ok
 
2028
    1  error
 
2029
*/
 
2030
 
 
2031
bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
 
2032
{
 
2033
  TABLE_LIST tables;
 
2034
  bzero((char*) &tables,sizeof(tables));
 
2035
  tables.db= (char*) "mysql";
 
2036
  tables.table_name= tables.alias= (char*) "proc";
 
2037
  *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) ||
 
2038
                 (!strcmp(sp->m_definer_user.str,
 
2039
                          thd->security_ctx->priv_user) &&
 
2040
                  !strcmp(sp->m_definer_host.str,
 
2041
                          thd->security_ctx->priv_host)));
 
2042
  if (!*full_access)
 
2043
    return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
 
2044
                                     sp->m_type == TYPE_ENUM_PROCEDURE);
 
2045
  return 0;
 
2046
}
 
2047
 
 
2048
 
 
2049
int
 
2050
sp_head::show_create_procedure(THD *thd)
 
2051
{
 
2052
  Protocol *protocol= thd->protocol;
 
2053
  char buff[2048];
 
2054
  String buffer(buff, sizeof(buff), system_charset_info);
 
2055
  int res;
 
2056
  List<Item> field_list;
 
2057
  byte *sql_mode_str;
 
2058
  ulong sql_mode_len;
 
2059
  bool full_access;
 
2060
  DBUG_ENTER("sp_head::show_create_procedure");
 
2061
  DBUG_PRINT("info", ("procedure %s", m_name.str));
 
2062
 
 
2063
  LINT_INIT(sql_mode_str);
 
2064
  LINT_INIT(sql_mode_len);
 
2065
 
 
2066
  if (check_show_routine_access(thd, this, &full_access))
 
2067
    DBUG_RETURN(1);
 
2068
 
 
2069
  sql_mode_str=
 
2070
    sys_var_thd_sql_mode::symbolic_mode_representation(thd,
 
2071
                                                       m_sql_mode,
 
2072
                                                       &sql_mode_len);
 
2073
  field_list.push_back(new Item_empty_string("Procedure", NAME_LEN));
 
2074
  field_list.push_back(new Item_empty_string("sql_mode", sql_mode_len));
 
2075
  // 1024 is for not to confuse old clients
 
2076
  Item_empty_string *definition=
 
2077
    new Item_empty_string("Create Procedure", max(buffer.length(),1024));
 
2078
  definition->maybe_null= TRUE;
 
2079
  field_list.push_back(definition);
 
2080
 
 
2081
  if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
 
2082
                                         Protocol::SEND_EOF))
 
2083
    DBUG_RETURN(1);
 
2084
  protocol->prepare_for_resend();
 
2085
  protocol->store(m_name.str, m_name.length, system_charset_info);
 
2086
  protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
 
2087
  if (full_access)
 
2088
    protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
 
2089
  else
 
2090
    protocol->store_null();
 
2091
  res= protocol->write();
 
2092
  send_eof(thd);
 
2093
 
 
2094
  DBUG_RETURN(res);
 
2095
}
 
2096
 
 
2097
 
 
2098
/*
 
2099
  Add instruction to SP
 
2100
 
 
2101
  SYNOPSIS
 
2102
    sp_head::add_instr()
 
2103
    instr   Instruction
 
2104
*/
 
2105
 
 
2106
void sp_head::add_instr(sp_instr *instr)
 
2107
{
 
2108
  instr->free_list= m_thd->free_list;
 
2109
  m_thd->free_list= 0;
 
2110
  /*
 
2111
    Memory root of every instruction is designated for permanent
 
2112
    transformations (optimizations) made on the parsed tree during
 
2113
    the first execution. It points to the memory root of the
 
2114
    entire stored procedure, as their life span is equal.
 
2115
  */
 
2116
  instr->mem_root= &main_mem_root;
 
2117
  insert_dynamic(&m_instr, (gptr)&instr);
 
2118
}
 
2119
 
 
2120
 
 
2121
int
 
2122
sp_head::show_create_function(THD *thd)
 
2123
{
 
2124
  Protocol *protocol= thd->protocol;
 
2125
  char buff[2048];
 
2126
  String buffer(buff, sizeof(buff), system_charset_info);
 
2127
  int res;
 
2128
  List<Item> field_list;
 
2129
  byte *sql_mode_str;
 
2130
  ulong sql_mode_len;
 
2131
  bool full_access;
 
2132
  DBUG_ENTER("sp_head::show_create_function");
 
2133
  DBUG_PRINT("info", ("procedure %s", m_name.str));
 
2134
  LINT_INIT(sql_mode_str);
 
2135
  LINT_INIT(sql_mode_len);
 
2136
 
 
2137
  if (check_show_routine_access(thd, this, &full_access))
 
2138
    DBUG_RETURN(1);
 
2139
 
 
2140
  sql_mode_str=
 
2141
    sys_var_thd_sql_mode::symbolic_mode_representation(thd,
 
2142
                                                       m_sql_mode,
 
2143
                                                       &sql_mode_len);
 
2144
  field_list.push_back(new Item_empty_string("Function",NAME_LEN));
 
2145
  field_list.push_back(new Item_empty_string("sql_mode", sql_mode_len));
 
2146
  Item_empty_string *definition=
 
2147
    new Item_empty_string("Create Function", max(buffer.length(),1024));
 
2148
  definition->maybe_null= TRUE;
 
2149
  field_list.push_back(definition);
 
2150
 
 
2151
  if (protocol->send_fields(&field_list,
 
2152
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
2153
    DBUG_RETURN(1);
 
2154
  protocol->prepare_for_resend();
 
2155
  protocol->store(m_name.str, m_name.length, system_charset_info);
 
2156
  protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
 
2157
  if (full_access)
 
2158
    protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
 
2159
  else
 
2160
    protocol->store_null();
 
2161
  res= protocol->write();
 
2162
  send_eof(thd);
 
2163
 
 
2164
  DBUG_RETURN(res);
 
2165
}
 
2166
 
 
2167
 
 
2168
/*
 
2169
  Do some minimal optimization of the code:
 
2170
    1) Mark used instructions
 
2171
       1.1) While doing this, shortcut jumps to jump instructions
 
2172
    2) Compact the code, removing unused instructions
 
2173
 
 
2174
  This is the main mark and move loop; it relies on the following methods
 
2175
  in sp_instr and its subclasses:
 
2176
 
 
2177
  opt_mark()           Mark instruction as reachable (will recurse for jumps)
 
2178
  opt_shortcut_jump()  Shortcut jumps to the final destination;
 
2179
                       used by opt_mark().
 
2180
  opt_move()           Update moved instruction
 
2181
  set_destination()    Set the new destination (jump instructions only)
 
2182
*/
 
2183
 
 
2184
void sp_head::optimize()
 
2185
{
 
2186
  List<sp_instr> bp;
 
2187
  sp_instr *i;
 
2188
  uint src, dst;
 
2189
 
 
2190
  opt_mark(0);
 
2191
 
 
2192
  bp.empty();
 
2193
  src= dst= 0;
 
2194
  while ((i= get_instr(src)))
 
2195
  {
 
2196
    if (! i->marked)
 
2197
    {
 
2198
      delete i;
 
2199
      src+= 1;
 
2200
    }
 
2201
    else
 
2202
    {
 
2203
      if (src != dst)
 
2204
      {                         // Move the instruction and update prev. jumps
 
2205
        sp_instr *ibp;
 
2206
        List_iterator_fast<sp_instr> li(bp);
 
2207
 
 
2208
        set_dynamic(&m_instr, (gptr)&i, dst);
 
2209
        while ((ibp= li++))
 
2210
        {
 
2211
          sp_instr_opt_meta *im= static_cast<sp_instr_opt_meta *>(ibp);
 
2212
          im->set_destination(src, dst);
 
2213
        }
 
2214
      }
 
2215
      i->opt_move(dst, &bp);
 
2216
      src+= 1;
 
2217
      dst+= 1;
 
2218
    }
 
2219
  }
 
2220
  m_instr.elements= dst;
 
2221
  bp.empty();
 
2222
}
 
2223
 
 
2224
void
 
2225
sp_head::opt_mark(uint ip)
 
2226
{
 
2227
  sp_instr *i;
 
2228
 
 
2229
  while ((i= get_instr(ip)) && !i->marked)
 
2230
    ip= i->opt_mark(this);
 
2231
}
 
2232
 
 
2233
 
 
2234
#ifndef DBUG_OFF
 
2235
/*
 
2236
  Return the routine instructions as a result set.
 
2237
  Returns 0 if ok, !=0 on error.
 
2238
*/
 
2239
int
 
2240
sp_head::show_routine_code(THD *thd)
 
2241
{
 
2242
  Protocol *protocol= thd->protocol;
 
2243
  char buff[2048];
 
2244
  String buffer(buff, sizeof(buff), system_charset_info);
 
2245
  List<Item> field_list;
 
2246
  sp_instr *i;
 
2247
  bool full_access;
 
2248
  int res= 0;
 
2249
  uint ip;
 
2250
  DBUG_ENTER("sp_head::show_routine_code");
 
2251
  DBUG_PRINT("info", ("procedure: %s", m_name.str));
 
2252
 
 
2253
  if (check_show_routine_access(thd, this, &full_access) || !full_access)
 
2254
    DBUG_RETURN(1);
 
2255
 
 
2256
  field_list.push_back(new Item_uint("Pos", 9));
 
2257
  // 1024 is for not to confuse old clients
 
2258
  field_list.push_back(new Item_empty_string("Instruction",
 
2259
                                             max(buffer.length(), 1024)));
 
2260
  if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
 
2261
                                         Protocol::SEND_EOF))
 
2262
    DBUG_RETURN(1);
 
2263
 
 
2264
  for (ip= 0; (i = get_instr(ip)) ; ip++)
 
2265
  {
 
2266
    /* 
 
2267
      Consistency check. If these are different something went wrong
 
2268
      during optimization.
 
2269
    */
 
2270
    if (ip != i->m_ip)
 
2271
    {
 
2272
      const char *format= "Instruction at position %u has m_ip=%u";
 
2273
      char tmp[sizeof(format) + 2*SP_INSTR_UINT_MAXLEN + 1];
 
2274
 
 
2275
      sprintf(tmp, format, ip, i->m_ip);
 
2276
      /*
 
2277
        Since this is for debugging purposes only, we don't bother to
 
2278
        introduce a special error code for it.
 
2279
      */
 
2280
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, tmp);
 
2281
    }
 
2282
    protocol->prepare_for_resend();
 
2283
    protocol->store((longlong)ip);
 
2284
 
 
2285
    buffer.set("", 0, system_charset_info);
 
2286
    i->print(&buffer);
 
2287
    protocol->store(buffer.ptr(), buffer.length(), system_charset_info);
 
2288
    if ((res= protocol->write()))
 
2289
      break;
 
2290
  }
 
2291
  send_eof(thd);
 
2292
 
 
2293
  DBUG_RETURN(res);
 
2294
}
 
2295
#endif // ifndef DBUG_OFF
 
2296
 
 
2297
 
 
2298
/*
 
2299
  Prepare LEX and thread for execution of instruction, if requested open
 
2300
  and lock LEX's tables, execute instruction's core function, perform
 
2301
  cleanup afterwards.
 
2302
 
 
2303
  SYNOPSIS
 
2304
    reset_lex_and_exec_core()
 
2305
      thd         - thread context
 
2306
      nextp       - out - next instruction
 
2307
      open_tables - if TRUE then check read access to tables in LEX's table
 
2308
                    list and open and lock them (used in instructions which
 
2309
                    need to calculate some expression and don't execute
 
2310
                    complete statement).
 
2311
      sp_instr    - instruction for which we prepare context, and which core
 
2312
                    function execute by calling its exec_core() method.
 
2313
 
 
2314
  NOTE
 
2315
    We are not saving/restoring some parts of THD which may need this because
 
2316
    we do this once for whole routine execution in sp_head::execute().
 
2317
 
 
2318
  RETURN VALUE
 
2319
    0/non-0 - Success/Failure
 
2320
*/
 
2321
 
 
2322
int
 
2323
sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
 
2324
                                       bool open_tables, sp_instr* instr)
 
2325
{
 
2326
  int res= 0;
 
2327
 
 
2328
  DBUG_ASSERT(!thd->derived_tables);
 
2329
  DBUG_ASSERT(thd->change_list.is_empty());
 
2330
  /*
 
2331
    Use our own lex.
 
2332
    We should not save old value since it is saved/restored in
 
2333
    sp_head::execute() when we are entering/leaving routine.
 
2334
  */
 
2335
  thd->lex= m_lex;
 
2336
 
 
2337
  VOID(pthread_mutex_lock(&LOCK_thread_count));
 
2338
  thd->query_id= next_query_id();
 
2339
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
2340
 
 
2341
  if (thd->prelocked_mode == NON_PRELOCKED)
 
2342
  {
 
2343
    /*
 
2344
      This statement will enter/leave prelocked mode on its own.
 
2345
      Entering prelocked mode changes table list and related members
 
2346
      of LEX, so we'll need to restore them.
 
2347
    */
 
2348
    if (lex_query_tables_own_last)
 
2349
    {
 
2350
      /*
 
2351
        We've already entered/left prelocked mode with this statement.
 
2352
        Attach the list of tables that need to be prelocked and mark m_lex
 
2353
        as having such list attached.
 
2354
      */
 
2355
      *lex_query_tables_own_last= prelocking_tables;
 
2356
      m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
 
2357
    }
 
2358
  }
 
2359
    
 
2360
  reinit_stmt_before_use(thd, m_lex);
 
2361
  /*
 
2362
    If requested check whenever we have access to tables in LEX's table list
 
2363
    and open and lock them before executing instructtions core function.
 
2364
  */
 
2365
  if (open_tables &&
 
2366
      (check_table_access(thd, SELECT_ACL, m_lex->query_tables, 0) ||
 
2367
       open_and_lock_tables(thd, m_lex->query_tables)))
 
2368
      res= -1;
 
2369
 
 
2370
  if (!res)
 
2371
    res= instr->exec_core(thd, nextp);
 
2372
 
 
2373
  m_lex->unit.cleanup();
 
2374
 
 
2375
  thd->proc_info="closing tables";
 
2376
  close_thread_tables(thd);
 
2377
  thd->proc_info= 0;
 
2378
 
 
2379
  if (m_lex->query_tables_own_last)
 
2380
  {
 
2381
    /*
 
2382
      We've entered and left prelocking mode when executing statement
 
2383
      stored in m_lex. 
 
2384
      m_lex->query_tables(->next_global)* list now has a 'tail' - a list
 
2385
      of tables that are added for prelocking. (If this is the first
 
2386
      execution, the 'tail' was added by open_tables(), otherwise we've
 
2387
      attached it above in this function).
 
2388
      Now we'll save the 'tail', and detach it.
 
2389
    */
 
2390
    lex_query_tables_own_last= m_lex->query_tables_own_last;
 
2391
    prelocking_tables= *lex_query_tables_own_last;
 
2392
    *lex_query_tables_own_last= NULL;
 
2393
    m_lex->mark_as_requiring_prelocking(NULL);
 
2394
  }
 
2395
  thd->rollback_item_tree_changes();
 
2396
  /* Update the state of the active arena. */
 
2397
  thd->stmt_arena->state= Query_arena::EXECUTED;
 
2398
 
 
2399
 
 
2400
  /*
 
2401
    Unlike for PS we should not call Item's destructors for newly created
 
2402
    items after execution of each instruction in stored routine. This is
 
2403
    because SP often create Item (like Item_int, Item_string etc...) when
 
2404
    they want to store some value in local variable, pass return value and
 
2405
    etc... So their life time should be longer than one instruction.
 
2406
 
 
2407
    cleanup_items() is called in sp_head::execute()
 
2408
  */
 
2409
  return res || thd->net.report_error;
 
2410
}
 
2411
 
 
2412
 
 
2413
/*
 
2414
  sp_instr class functions
 
2415
*/
 
2416
 
 
2417
int sp_instr::exec_core(THD *thd, uint *nextp)
 
2418
{
 
2419
  DBUG_ASSERT(0);
 
2420
  return 0;
 
2421
}
 
2422
 
 
2423
/*
 
2424
  sp_instr_stmt class functions
 
2425
*/
 
2426
 
 
2427
int
 
2428
sp_instr_stmt::execute(THD *thd, uint *nextp)
 
2429
{
 
2430
  char *query;
 
2431
  uint32 query_length;
 
2432
  int res;
 
2433
  DBUG_ENTER("sp_instr_stmt::execute");
 
2434
  DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
 
2435
 
 
2436
  query= thd->query;
 
2437
  query_length= thd->query_length;
 
2438
  if (!(res= alloc_query(thd, m_query.str, m_query.length+1)) &&
 
2439
      !(res=subst_spvars(thd, this, &m_query)))
 
2440
  {
 
2441
    /*
 
2442
      (the order of query cache and subst_spvars calls is irrelevant because
 
2443
      queries with SP vars can't be cached)
 
2444
    */
 
2445
    if (query_cache_send_result_to_client(thd,
 
2446
                                          thd->query, thd->query_length) <= 0)
 
2447
    {
 
2448
      res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
 
2449
      query_cache_end_of_result(thd);
 
2450
    }
 
2451
    else
 
2452
      *nextp= m_ip+1;
 
2453
    thd->query= query;
 
2454
    thd->query_length= query_length;
 
2455
  }
 
2456
  DBUG_RETURN(res);
 
2457
}
 
2458
 
 
2459
 
 
2460
void
 
2461
sp_instr_stmt::print(String *str)
 
2462
{
 
2463
  uint i, len;
 
2464
 
 
2465
  /* stmt CMD "..." */
 
2466
  if (str->reserve(SP_STMT_PRINT_MAXLEN+SP_INSTR_UINT_MAXLEN+8))
 
2467
    return;
 
2468
  str->qs_append(STRING_WITH_LEN("stmt "));
 
2469
  str->qs_append((uint)m_lex_keeper.sql_command());
 
2470
  str->qs_append(STRING_WITH_LEN(" \""));
 
2471
  len= m_query.length;
 
2472
  /*
 
2473
    Print the query string (but not too much of it), just to indicate which
 
2474
    statement it is.
 
2475
  */
 
2476
  if (len > SP_STMT_PRINT_MAXLEN)
 
2477
    len= SP_STMT_PRINT_MAXLEN-3;
 
2478
  /* Copy the query string and replace '\n' with ' ' in the process */
 
2479
  for (i= 0 ; i < len ; i++)
 
2480
  {
 
2481
    char c= m_query.str[i];
 
2482
    if (c == '\n')
 
2483
      c= ' ';
 
2484
    str->qs_append(c);
 
2485
  }
 
2486
  if (m_query.length > SP_STMT_PRINT_MAXLEN)
 
2487
    str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */
 
2488
  str->qs_append('"');
 
2489
}
 
2490
 
 
2491
 
 
2492
int
 
2493
sp_instr_stmt::exec_core(THD *thd, uint *nextp)
 
2494
{
 
2495
  int res= mysql_execute_command(thd);
 
2496
  *nextp= m_ip+1;
 
2497
  return res;
 
2498
}
 
2499
 
 
2500
 
 
2501
/*
 
2502
  sp_instr_set class functions
 
2503
*/
 
2504
 
 
2505
int
 
2506
sp_instr_set::execute(THD *thd, uint *nextp)
 
2507
{
 
2508
  DBUG_ENTER("sp_instr_set::execute");
 
2509
  DBUG_PRINT("info", ("offset: %u", m_offset));
 
2510
 
 
2511
  DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
 
2512
}
 
2513
 
 
2514
 
 
2515
int
 
2516
sp_instr_set::exec_core(THD *thd, uint *nextp)
 
2517
{
 
2518
  int res= thd->spcont->set_variable(thd, m_offset, &m_value);
 
2519
 
 
2520
  if (res && thd->spcont->found_handler_here())
 
2521
  {
 
2522
    /*
 
2523
      Failed to evaluate the value, and a handler has been found. Reset the
 
2524
      variable to NULL.
 
2525
    */
 
2526
 
 
2527
    if (thd->spcont->set_variable(thd, m_offset, 0))
 
2528
    {
 
2529
      /* If this also failed, let's abort. */
 
2530
 
 
2531
      sp_rcontext *spcont= thd->spcont;
 
2532
    
 
2533
      thd->spcont= 0;           /* Avoid handlers */
 
2534
      my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
2535
      spcont->clear_handler();
 
2536
      thd->spcont= spcont;
 
2537
    }
 
2538
  }
 
2539
 
 
2540
  *nextp = m_ip+1;
 
2541
  return res;
 
2542
}
 
2543
 
 
2544
void
 
2545
sp_instr_set::print(String *str)
 
2546
{
 
2547
  /* set name@offset ... */
 
2548
  int rsrv = SP_INSTR_UINT_MAXLEN+6;
 
2549
  sp_variable_t *var = m_ctx->find_variable(m_offset);
 
2550
 
 
2551
  /* 'var' should always be non-null, but just in case... */
 
2552
  if (var)
 
2553
    rsrv+= var->name.length;
 
2554
  if (str->reserve(rsrv))
 
2555
    return;
 
2556
  str->qs_append(STRING_WITH_LEN("set "));
 
2557
  if (var)
 
2558
  {
 
2559
    str->qs_append(var->name.str, var->name.length);
 
2560
    str->qs_append('@');
 
2561
  }
 
2562
  str->qs_append(m_offset);
 
2563
  str->qs_append(' ');
 
2564
  m_value->print(str);
 
2565
}
 
2566
 
 
2567
 
 
2568
/*
 
2569
  sp_instr_set_trigger_field class functions
 
2570
*/
 
2571
 
 
2572
int
 
2573
sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
 
2574
{
 
2575
  DBUG_ENTER("sp_instr_set_trigger_field::execute");
 
2576
  DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
 
2577
}
 
2578
 
 
2579
 
 
2580
int
 
2581
sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
 
2582
{
 
2583
  const int res= (trigger_field->set_value(thd, &value) ? -1 : 0);
 
2584
  *nextp = m_ip+1;
 
2585
  return res;
 
2586
}
 
2587
 
 
2588
void
 
2589
sp_instr_set_trigger_field::print(String *str)
 
2590
{
 
2591
  str->append(STRING_WITH_LEN("set_trigger_field "));
 
2592
  trigger_field->print(str);
 
2593
  str->append(STRING_WITH_LEN(":="));
 
2594
  value->print(str);
 
2595
}
 
2596
 
 
2597
 
 
2598
/*
 
2599
 sp_instr_jump class functions
 
2600
*/
 
2601
 
 
2602
int
 
2603
sp_instr_jump::execute(THD *thd, uint *nextp)
 
2604
{
 
2605
  DBUG_ENTER("sp_instr_jump::execute");
 
2606
  DBUG_PRINT("info", ("destination: %u", m_dest));
 
2607
 
 
2608
  *nextp= m_dest;
 
2609
  DBUG_RETURN(0);
 
2610
}
 
2611
 
 
2612
void
 
2613
sp_instr_jump::print(String *str)
 
2614
{
 
2615
  /* jump dest */
 
2616
  if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
 
2617
    return;
 
2618
  str->qs_append(STRING_WITH_LEN("jump "));
 
2619
  str->qs_append(m_dest);
 
2620
}
 
2621
 
 
2622
uint
 
2623
sp_instr_jump::opt_mark(sp_head *sp)
 
2624
{
 
2625
  m_dest= opt_shortcut_jump(sp, this);
 
2626
  if (m_dest != m_ip+1)         /* Jumping to following instruction? */
 
2627
    marked= 1;
 
2628
  m_optdest= sp->get_instr(m_dest);
 
2629
  return m_dest;
 
2630
}
 
2631
 
 
2632
uint
 
2633
sp_instr_jump::opt_shortcut_jump(sp_head *sp, sp_instr *start)
 
2634
{
 
2635
  uint dest= m_dest;
 
2636
  sp_instr *i;
 
2637
 
 
2638
  while ((i= sp->get_instr(dest)))
 
2639
  {
 
2640
    uint ndest;
 
2641
 
 
2642
    if (start == i || this == i)
 
2643
      break;
 
2644
    ndest= i->opt_shortcut_jump(sp, start);
 
2645
    if (ndest == dest)
 
2646
      break;
 
2647
    dest= ndest;
 
2648
  }
 
2649
  return dest;
 
2650
}
 
2651
 
 
2652
void
 
2653
sp_instr_jump::opt_move(uint dst, List<sp_instr> *bp)
 
2654
{
 
2655
  if (m_dest > m_ip)
 
2656
    bp->push_back(this);        // Forward
 
2657
  else if (m_optdest)
 
2658
    m_dest= m_optdest->m_ip;    // Backward
 
2659
  m_ip= dst;
 
2660
}
 
2661
 
 
2662
 
 
2663
/*
 
2664
  sp_instr_jump_if_not class functions
 
2665
*/
 
2666
 
 
2667
int
 
2668
sp_instr_jump_if_not::execute(THD *thd, uint *nextp)
 
2669
{
 
2670
  DBUG_ENTER("sp_instr_jump_if_not::execute");
 
2671
  DBUG_PRINT("info", ("destination: %u", m_dest));
 
2672
  DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
 
2673
}
 
2674
 
 
2675
 
 
2676
int
 
2677
sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
 
2678
{
 
2679
  Item *it;
 
2680
  int res;
 
2681
 
 
2682
  it= sp_prepare_func_item(thd, &m_expr);
 
2683
  if (! it)
 
2684
  {
 
2685
    res= -1;
 
2686
    *nextp = m_cont_dest;
 
2687
  }
 
2688
  else
 
2689
  {
 
2690
    res= 0;
 
2691
    if (! it->val_bool())
 
2692
      *nextp = m_dest;
 
2693
    else
 
2694
      *nextp = m_ip+1;
 
2695
  }
 
2696
 
 
2697
  return res;
 
2698
}
 
2699
 
 
2700
 
 
2701
void
 
2702
sp_instr_jump_if_not::print(String *str)
 
2703
{
 
2704
  /* jump_if_not dest(cont) ... */
 
2705
  if (str->reserve(2*SP_INSTR_UINT_MAXLEN+14+32)) // Add some for the expr. too
 
2706
    return;
 
2707
  str->qs_append(STRING_WITH_LEN("jump_if_not "));
 
2708
  str->qs_append(m_dest);
 
2709
  str->qs_append('(');
 
2710
  str->qs_append(m_cont_dest);
 
2711
  str->qs_append(STRING_WITH_LEN(") "));
 
2712
  m_expr->print(str);
 
2713
}
 
2714
 
 
2715
 
 
2716
uint
 
2717
sp_instr_jump_if_not::opt_mark(sp_head *sp)
 
2718
{
 
2719
  sp_instr *i;
 
2720
 
 
2721
  marked= 1;
 
2722
  if ((i= sp->get_instr(m_dest)))
 
2723
  {
 
2724
    m_dest= i->opt_shortcut_jump(sp, this);
 
2725
    m_optdest= sp->get_instr(m_dest);
 
2726
  }
 
2727
  sp->opt_mark(m_dest);
 
2728
  if ((i= sp->get_instr(m_cont_dest)))
 
2729
  {
 
2730
    m_cont_dest= i->opt_shortcut_jump(sp, this);
 
2731
    m_cont_optdest= sp->get_instr(m_cont_dest);
 
2732
  }
 
2733
  sp->opt_mark(m_cont_dest);
 
2734
  return m_ip+1;
 
2735
}
 
2736
 
 
2737
void
 
2738
sp_instr_jump_if_not::opt_move(uint dst, List<sp_instr> *bp)
 
2739
{
 
2740
  /*
 
2741
    cont. destinations may point backwards after shortcutting jumps
 
2742
    during the mark phase. If it's still pointing forwards, only
 
2743
    push this for backpatching if sp_instr_jump::opt_move() will not
 
2744
    do it (i.e. if the m_dest points backwards).
 
2745
   */
 
2746
  if (m_cont_dest > m_ip)
 
2747
  {                             // Forward
 
2748
    if (m_dest < m_ip)
 
2749
      bp->push_back(this);
 
2750
  }
 
2751
  else if (m_cont_optdest)
 
2752
    m_cont_dest= m_cont_optdest->m_ip; // Backward
 
2753
  /* This will take care of m_dest and m_ip */
 
2754
  sp_instr_jump::opt_move(dst, bp);
 
2755
}
 
2756
 
 
2757
 
 
2758
/*
 
2759
  sp_instr_freturn class functions
 
2760
*/
 
2761
 
 
2762
int
 
2763
sp_instr_freturn::execute(THD *thd, uint *nextp)
 
2764
{
 
2765
  DBUG_ENTER("sp_instr_freturn::execute");
 
2766
  DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
 
2767
}
 
2768
 
 
2769
 
 
2770
int
 
2771
sp_instr_freturn::exec_core(THD *thd, uint *nextp)
 
2772
{
 
2773
  /*
 
2774
    Change <next instruction pointer>, so that this will be the last
 
2775
    instruction in the stored function.
 
2776
  */
 
2777
 
 
2778
  *nextp= UINT_MAX;
 
2779
 
 
2780
  /*
 
2781
    Evaluate the value of return expression and store it in current runtime
 
2782
    context.
 
2783
 
 
2784
    NOTE: It's necessary to evaluate result item right here, because we must
 
2785
    do it in scope of execution the current context/block.
 
2786
  */
 
2787
 
 
2788
  return thd->spcont->set_return_value(thd, &m_value);
 
2789
}
 
2790
 
 
2791
void
 
2792
sp_instr_freturn::print(String *str)
 
2793
{
 
2794
  /* freturn type expr... */
 
2795
  if (str->reserve(1024+8+32)) // Add some for the expr. too
 
2796
    return;
 
2797
  str->qs_append(STRING_WITH_LEN("freturn "));
 
2798
  str->qs_append((uint)m_type);
 
2799
  str->qs_append(' ');
 
2800
  m_value->print(str);
 
2801
}
 
2802
 
 
2803
/*
 
2804
  sp_instr_hpush_jump class functions
 
2805
*/
 
2806
 
 
2807
int
 
2808
sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
 
2809
{
 
2810
  DBUG_ENTER("sp_instr_hpush_jump::execute");
 
2811
  List_iterator_fast<sp_cond_type_t> li(m_cond);
 
2812
  sp_cond_type_t *p;
 
2813
 
 
2814
  while ((p= li++))
 
2815
    thd->spcont->push_handler(p, m_ip+1, m_type, m_frame);
 
2816
 
 
2817
  *nextp= m_dest;
 
2818
  DBUG_RETURN(0);
 
2819
}
 
2820
 
 
2821
 
 
2822
void
 
2823
sp_instr_hpush_jump::print(String *str)
 
2824
{
 
2825
  /* hpush_jump dest fsize type */
 
2826
  if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 21))
 
2827
    return;
 
2828
  str->qs_append(STRING_WITH_LEN("hpush_jump "));
 
2829
  str->qs_append(m_dest);
 
2830
  str->qs_append(' ');
 
2831
  str->qs_append(m_frame);
 
2832
  switch (m_type) {
 
2833
  case SP_HANDLER_NONE:
 
2834
    str->qs_append(STRING_WITH_LEN(" NONE")); // This would be a bug
 
2835
    break;
 
2836
  case SP_HANDLER_EXIT:
 
2837
    str->qs_append(STRING_WITH_LEN(" EXIT"));
 
2838
    break;
 
2839
  case SP_HANDLER_CONTINUE:
 
2840
    str->qs_append(STRING_WITH_LEN(" CONTINUE"));
 
2841
    break;
 
2842
  case SP_HANDLER_UNDO:
 
2843
    str->qs_append(STRING_WITH_LEN(" UNDO"));
 
2844
    break;
 
2845
  default:
 
2846
    // This would be a bug as well
 
2847
    str->qs_append(STRING_WITH_LEN(" UNKNOWN:"));
 
2848
    str->qs_append(m_type);
 
2849
  }
 
2850
}
 
2851
 
 
2852
 
 
2853
uint
 
2854
sp_instr_hpush_jump::opt_mark(sp_head *sp)
 
2855
{
 
2856
  sp_instr *i;
 
2857
 
 
2858
  marked= 1;
 
2859
  if ((i= sp->get_instr(m_dest)))
 
2860
  {
 
2861
    m_dest= i->opt_shortcut_jump(sp, this);
 
2862
    m_optdest= sp->get_instr(m_dest);
 
2863
  }
 
2864
  sp->opt_mark(m_dest);
 
2865
  return m_ip+1;
 
2866
}
 
2867
 
 
2868
 
 
2869
/*
 
2870
  sp_instr_hpop class functions
 
2871
*/
 
2872
 
 
2873
int
 
2874
sp_instr_hpop::execute(THD *thd, uint *nextp)
 
2875
{
 
2876
  DBUG_ENTER("sp_instr_hpop::execute");
 
2877
  thd->spcont->pop_handlers(m_count);
 
2878
  *nextp= m_ip+1;
 
2879
  DBUG_RETURN(0);
 
2880
}
 
2881
 
 
2882
void
 
2883
sp_instr_hpop::print(String *str)
 
2884
{
 
2885
  /* hpop count */
 
2886
  if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
 
2887
    return;
 
2888
  str->qs_append(STRING_WITH_LEN("hpop "));
 
2889
  str->qs_append(m_count);
 
2890
}
 
2891
 
 
2892
 
 
2893
/*
 
2894
  sp_instr_hreturn class functions
 
2895
*/
 
2896
 
 
2897
int
 
2898
sp_instr_hreturn::execute(THD *thd, uint *nextp)
 
2899
{
 
2900
  DBUG_ENTER("sp_instr_hreturn::execute");
 
2901
  if (m_dest)
 
2902
    *nextp= m_dest;
 
2903
  else
 
2904
  {
 
2905
    *nextp= thd->spcont->pop_hstack();
 
2906
  }
 
2907
  thd->spcont->exit_handler();
 
2908
  DBUG_RETURN(0);
 
2909
}
 
2910
 
 
2911
 
 
2912
void
 
2913
sp_instr_hreturn::print(String *str)
 
2914
{
 
2915
  /* hreturn framesize dest */
 
2916
  if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 9))
 
2917
    return;
 
2918
  str->qs_append(STRING_WITH_LEN("hreturn "));
 
2919
  str->qs_append(m_frame);
 
2920
  if (m_dest)
 
2921
  {
 
2922
    str->qs_append(' ');
 
2923
    str->qs_append(m_dest);
 
2924
  }
 
2925
}
 
2926
 
 
2927
 
 
2928
uint
 
2929
sp_instr_hreturn::opt_mark(sp_head *sp)
 
2930
{
 
2931
  if (m_dest)
 
2932
    return sp_instr_jump::opt_mark(sp);
 
2933
  else
 
2934
  {
 
2935
    marked= 1;
 
2936
    return UINT_MAX;
 
2937
  }
 
2938
}
 
2939
 
 
2940
 
 
2941
/*
 
2942
  sp_instr_cpush class functions
 
2943
*/
 
2944
 
 
2945
int
 
2946
sp_instr_cpush::execute(THD *thd, uint *nextp)
 
2947
{
 
2948
  Query_arena backup_arena;
 
2949
  DBUG_ENTER("sp_instr_cpush::execute");
 
2950
 
 
2951
  /*
 
2952
    We should create cursors in the callers arena, as
 
2953
    it could be (and usually is) used in several instructions.
 
2954
  */
 
2955
  thd->set_n_backup_active_arena(thd->spcont->callers_arena, &backup_arena);
 
2956
 
 
2957
  thd->spcont->push_cursor(&m_lex_keeper, this);
 
2958
 
 
2959
  thd->restore_active_arena(thd->spcont->callers_arena, &backup_arena);
 
2960
 
 
2961
  *nextp= m_ip+1;
 
2962
 
 
2963
  DBUG_RETURN(0);
 
2964
}
 
2965
 
 
2966
 
 
2967
void
 
2968
sp_instr_cpush::print(String *str)
 
2969
{
 
2970
  LEX_STRING n;
 
2971
  my_bool found= m_ctx->find_cursor(m_cursor, &n);
 
2972
  /* cpush name@offset */
 
2973
  uint rsrv= SP_INSTR_UINT_MAXLEN+7;
 
2974
 
 
2975
  if (found)
 
2976
    rsrv+= n.length;
 
2977
  if (str->reserve(rsrv))
 
2978
    return;
 
2979
  str->qs_append(STRING_WITH_LEN("cpush "));
 
2980
  if (found)
 
2981
  {
 
2982
    str->qs_append(n.str, n.length);
 
2983
    str->qs_append('@');
 
2984
  }
 
2985
  str->qs_append(m_cursor);
 
2986
}
 
2987
 
 
2988
 
 
2989
/*
 
2990
  sp_instr_cpop class functions
 
2991
*/
 
2992
 
 
2993
int
 
2994
sp_instr_cpop::execute(THD *thd, uint *nextp)
 
2995
{
 
2996
  DBUG_ENTER("sp_instr_cpop::execute");
 
2997
  thd->spcont->pop_cursors(m_count);
 
2998
  *nextp= m_ip+1;
 
2999
  DBUG_RETURN(0);
 
3000
}
 
3001
 
 
3002
 
 
3003
void
 
3004
sp_instr_cpop::print(String *str)
 
3005
{
 
3006
  /* cpop count */
 
3007
  if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
 
3008
    return;
 
3009
  str->qs_append(STRING_WITH_LEN("cpop "));
 
3010
  str->qs_append(m_count);
 
3011
}
 
3012
 
 
3013
 
 
3014
/*
 
3015
  sp_instr_copen class functions
 
3016
*/
 
3017
 
 
3018
int
 
3019
sp_instr_copen::execute(THD *thd, uint *nextp)
 
3020
{
 
3021
  /*
 
3022
    We don't store a pointer to the cursor in the instruction to be
 
3023
    able to reuse the same instruction among different threads in future.
 
3024
  */
 
3025
  sp_cursor *c= thd->spcont->get_cursor(m_cursor);
 
3026
  int res;
 
3027
  DBUG_ENTER("sp_instr_copen::execute");
 
3028
 
 
3029
  if (! c)
 
3030
    res= -1;
 
3031
  else
 
3032
  {
 
3033
    sp_lex_keeper *lex_keeper= c->get_lex_keeper();
 
3034
    Query_arena *old_arena= thd->stmt_arena;
 
3035
 
 
3036
    /*
 
3037
      Get the Query_arena from the cpush instruction, which contains
 
3038
      the free_list of the query, so new items (if any) are stored in
 
3039
      the right free_list, and we can cleanup after each open.
 
3040
    */
 
3041
    thd->stmt_arena= c->get_instr();
 
3042
    res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
 
3043
    /* Cleanup the query's items */
 
3044
    if (thd->stmt_arena->free_list)
 
3045
      cleanup_items(thd->stmt_arena->free_list);
 
3046
    thd->stmt_arena= old_arena;
 
3047
    /*
 
3048
      Work around the fact that errors in selects are not returned properly
 
3049
      (but instead converted into a warning), so if a condition handler
 
3050
      caught, we have lost the result code.
 
3051
    */
 
3052
    if (!res)
 
3053
    {
 
3054
      uint dummy1, dummy2;
 
3055
 
 
3056
      if (thd->spcont->found_handler(&dummy1, &dummy2))
 
3057
        res= -1;
 
3058
    }
 
3059
    /* TODO: Assert here that we either have an error or a cursor */
 
3060
  }
 
3061
  DBUG_RETURN(res);
 
3062
}
 
3063
 
 
3064
 
 
3065
int
 
3066
sp_instr_copen::exec_core(THD *thd, uint *nextp)
 
3067
{
 
3068
  sp_cursor *c= thd->spcont->get_cursor(m_cursor);
 
3069
  int res= c->open(thd);
 
3070
  *nextp= m_ip+1;
 
3071
  return res;
 
3072
}
 
3073
 
 
3074
void
 
3075
sp_instr_copen::print(String *str)
 
3076
{
 
3077
  LEX_STRING n;
 
3078
  my_bool found= m_ctx->find_cursor(m_cursor, &n);
 
3079
  /* copen name@offset */
 
3080
  uint rsrv= SP_INSTR_UINT_MAXLEN+7;
 
3081
 
 
3082
  if (found)
 
3083
    rsrv+= n.length;
 
3084
  if (str->reserve(rsrv))
 
3085
    return;
 
3086
  str->qs_append(STRING_WITH_LEN("copen "));
 
3087
  if (found)
 
3088
  {
 
3089
    str->qs_append(n.str, n.length);
 
3090
    str->qs_append('@');
 
3091
  }
 
3092
  str->qs_append(m_cursor);
 
3093
}
 
3094
 
 
3095
 
 
3096
/*
 
3097
  sp_instr_cclose class functions
 
3098
*/
 
3099
 
 
3100
int
 
3101
sp_instr_cclose::execute(THD *thd, uint *nextp)
 
3102
{
 
3103
  sp_cursor *c= thd->spcont->get_cursor(m_cursor);
 
3104
  int res;
 
3105
  DBUG_ENTER("sp_instr_cclose::execute");
 
3106
 
 
3107
  if (! c)
 
3108
    res= -1;
 
3109
  else
 
3110
    res= c->close(thd);
 
3111
  *nextp= m_ip+1;
 
3112
  DBUG_RETURN(res);
 
3113
}
 
3114
 
 
3115
 
 
3116
void
 
3117
sp_instr_cclose::print(String *str)
 
3118
{
 
3119
  LEX_STRING n;
 
3120
  my_bool found= m_ctx->find_cursor(m_cursor, &n);
 
3121
  /* cclose name@offset */
 
3122
  uint rsrv= SP_INSTR_UINT_MAXLEN+8;
 
3123
 
 
3124
  if (found)
 
3125
    rsrv+= n.length;
 
3126
  if (str->reserve(rsrv))
 
3127
    return;
 
3128
  str->qs_append(STRING_WITH_LEN("cclose "));
 
3129
  if (found)
 
3130
  {
 
3131
    str->qs_append(n.str, n.length);
 
3132
    str->qs_append('@');
 
3133
  }
 
3134
  str->qs_append(m_cursor);
 
3135
}
 
3136
 
 
3137
 
 
3138
/*
 
3139
  sp_instr_cfetch class functions
 
3140
*/
 
3141
 
 
3142
int
 
3143
sp_instr_cfetch::execute(THD *thd, uint *nextp)
 
3144
{
 
3145
  sp_cursor *c= thd->spcont->get_cursor(m_cursor);
 
3146
  int res;
 
3147
  Query_arena backup_arena;
 
3148
  DBUG_ENTER("sp_instr_cfetch::execute");
 
3149
 
 
3150
  res= c ? c->fetch(thd, &m_varlist) : -1;
 
3151
 
 
3152
  *nextp= m_ip+1;
 
3153
  DBUG_RETURN(res);
 
3154
}
 
3155
 
 
3156
 
 
3157
void
 
3158
sp_instr_cfetch::print(String *str)
 
3159
{
 
3160
  List_iterator_fast<struct sp_variable> li(m_varlist);
 
3161
  sp_variable_t *pv;
 
3162
  LEX_STRING n;
 
3163
  my_bool found= m_ctx->find_cursor(m_cursor, &n);
 
3164
  /* cfetch name@offset vars... */
 
3165
  uint rsrv= SP_INSTR_UINT_MAXLEN+8;
 
3166
 
 
3167
  if (found)
 
3168
    rsrv+= n.length;
 
3169
  if (str->reserve(rsrv))
 
3170
    return;
 
3171
  str->qs_append(STRING_WITH_LEN("cfetch "));
 
3172
  if (found)
 
3173
  {
 
3174
    str->qs_append(n.str, n.length);
 
3175
    str->qs_append('@');
 
3176
  }
 
3177
  str->qs_append(m_cursor);
 
3178
  while ((pv= li++))
 
3179
  {
 
3180
    if (str->reserve(pv->name.length+SP_INSTR_UINT_MAXLEN+2))
 
3181
      return;
 
3182
    str->qs_append(' ');
 
3183
    str->qs_append(pv->name.str, pv->name.length);
 
3184
    str->qs_append('@');
 
3185
    str->qs_append(pv->offset);
 
3186
  }
 
3187
}
 
3188
 
 
3189
 
 
3190
/*
 
3191
  sp_instr_error class functions
 
3192
*/
 
3193
 
 
3194
int
 
3195
sp_instr_error::execute(THD *thd, uint *nextp)
 
3196
{
 
3197
  DBUG_ENTER("sp_instr_error::execute");
 
3198
 
 
3199
  my_message(m_errcode, ER(m_errcode), MYF(0));
 
3200
  *nextp= m_ip+1;
 
3201
  DBUG_RETURN(-1);
 
3202
}
 
3203
 
 
3204
 
 
3205
void
 
3206
sp_instr_error::print(String *str)
 
3207
{
 
3208
  /* error code */
 
3209
  if (str->reserve(SP_INSTR_UINT_MAXLEN+6))
 
3210
    return;
 
3211
  str->qs_append(STRING_WITH_LEN("error "));
 
3212
  str->qs_append(m_errcode);
 
3213
}
 
3214
 
 
3215
 
 
3216
/**************************************************************************
 
3217
  sp_instr_set_case_expr class implementation
 
3218
**************************************************************************/
 
3219
 
 
3220
int
 
3221
sp_instr_set_case_expr::execute(THD *thd, uint *nextp)
 
3222
{
 
3223
  DBUG_ENTER("sp_instr_set_case_expr::execute");
 
3224
 
 
3225
  DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
 
3226
}
 
3227
 
 
3228
 
 
3229
int
 
3230
sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
 
3231
{
 
3232
  int res= thd->spcont->set_case_expr(thd, m_case_expr_id, &m_case_expr);
 
3233
 
 
3234
  if (res &&
 
3235
      !thd->spcont->get_case_expr(m_case_expr_id) &&
 
3236
      thd->spcont->found_handler_here())
 
3237
  {
 
3238
    /*
 
3239
      Failed to evaluate the value, the case expression is still not
 
3240
      initialized, and a handler has been found. Set to NULL so we can continue.
 
3241
    */
 
3242
 
 
3243
    Item *null_item= new Item_null();
 
3244
    
 
3245
    if (!null_item ||
 
3246
        thd->spcont->set_case_expr(thd, m_case_expr_id, &null_item))
 
3247
    {
 
3248
      /* If this also failed, we have to abort. */
 
3249
 
 
3250
      sp_rcontext *spcont= thd->spcont;
 
3251
    
 
3252
      thd->spcont= 0;           /* Avoid handlers */
 
3253
      my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
3254
      spcont->clear_handler();
 
3255
      thd->spcont= spcont;
 
3256
    }
 
3257
    *nextp= m_cont_dest;        /* For continue handler */
 
3258
  }
 
3259
  else
 
3260
    *nextp= m_ip+1;
 
3261
 
 
3262
  return res;
 
3263
}
 
3264
 
 
3265
 
 
3266
void
 
3267
sp_instr_set_case_expr::print(String *str)
 
3268
{
 
3269
  /* set_case_expr (cont) id ... */
 
3270
  str->reserve(2*SP_INSTR_UINT_MAXLEN+18+32); // Add some extra for expr too
 
3271
  str->qs_append(STRING_WITH_LEN("set_case_expr ("));
 
3272
  str->qs_append(m_cont_dest);
 
3273
  str->qs_append(STRING_WITH_LEN(") "));
 
3274
  str->qs_append(m_case_expr_id);
 
3275
  str->qs_append(' ');
 
3276
  m_case_expr->print(str);
 
3277
}
 
3278
 
 
3279
uint
 
3280
sp_instr_set_case_expr::opt_mark(sp_head *sp)
 
3281
{
 
3282
  sp_instr *i;
 
3283
 
 
3284
  marked= 1;
 
3285
  if ((i= sp->get_instr(m_cont_dest)))
 
3286
  {
 
3287
    m_cont_dest= i->opt_shortcut_jump(sp, this);
 
3288
    m_cont_optdest= sp->get_instr(m_cont_dest);
 
3289
  }
 
3290
  sp->opt_mark(m_cont_dest);
 
3291
  return m_ip+1;
 
3292
}
 
3293
 
 
3294
void
 
3295
sp_instr_set_case_expr::opt_move(uint dst, List<sp_instr> *bp)
 
3296
{
 
3297
  if (m_cont_dest > m_ip)
 
3298
    bp->push_back(this);        // Forward
 
3299
  else if (m_cont_optdest)
 
3300
    m_cont_dest= m_cont_optdest->m_ip; // Backward
 
3301
  m_ip= dst;
 
3302
}
 
3303
 
 
3304
 
 
3305
/* ------------------------------------------------------------------ */
 
3306
 
 
3307
/*
 
3308
  Security context swapping
 
3309
*/
 
3310
 
 
3311
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
3312
bool
 
3313
sp_change_security_context(THD *thd, sp_head *sp, Security_context **backup)
 
3314
{
 
3315
  *backup= 0;
 
3316
  if (sp->m_chistics->suid != SP_IS_NOT_SUID &&
 
3317
      (strcmp(sp->m_definer_user.str,
 
3318
              thd->security_ctx->priv_user) ||
 
3319
       my_strcasecmp(system_charset_info, sp->m_definer_host.str,
 
3320
                     thd->security_ctx->priv_host)))
 
3321
  {
 
3322
    if (acl_getroot_no_password(&sp->m_security_ctx, sp->m_definer_user.str,
 
3323
                                sp->m_definer_host.str,
 
3324
                                sp->m_definer_host.str,
 
3325
                                sp->m_db.str))
 
3326
    {
 
3327
      my_error(ER_NO_SUCH_USER, MYF(0), sp->m_definer_user.str,
 
3328
               sp->m_definer_host.str);
 
3329
      return TRUE;
 
3330
    }
 
3331
    *backup= thd->security_ctx;
 
3332
    thd->security_ctx= &sp->m_security_ctx;
 
3333
  }
 
3334
  return FALSE;
 
3335
}
 
3336
 
 
3337
void
 
3338
sp_restore_security_context(THD *thd, Security_context *backup)
 
3339
{
 
3340
  if (backup)
 
3341
    thd->security_ctx= backup;
 
3342
}
 
3343
 
 
3344
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
 
3345
 
 
3346
/*
 
3347
  Structure that represent all instances of one table
 
3348
  in optimized multi-set of tables used by routine.
 
3349
*/
 
3350
 
 
3351
typedef struct st_sp_table
 
3352
{
 
3353
  /*
 
3354
    Multi-set key:
 
3355
      db_name\0table_name\0alias\0 - for normal tables
 
3356
      db_name\0table_name\0        - for temporary tables
 
3357
    Note that in both cases we don't take last '\0' into account when
 
3358
    we count length of key.
 
3359
  */
 
3360
  LEX_STRING qname;
 
3361
  uint db_length, table_name_length;
 
3362
  bool temp;               /* true if corresponds to a temporary table */
 
3363
  thr_lock_type lock_type; /* lock type used for prelocking */
 
3364
  uint lock_count;
 
3365
  uint query_lock_count;
 
3366
} SP_TABLE;
 
3367
 
 
3368
byte *
 
3369
sp_table_key(const byte *ptr, uint *plen, my_bool first)
 
3370
{
 
3371
  SP_TABLE *tab= (SP_TABLE *)ptr;
 
3372
  *plen= tab->qname.length;
 
3373
  return (byte *)tab->qname.str;
 
3374
}
 
3375
 
 
3376
 
 
3377
/*
 
3378
  Merge the list of tables used by some query into the multi-set of
 
3379
  tables used by routine.
 
3380
 
 
3381
  SYNOPSIS
 
3382
    merge_table_list()
 
3383
      thd               - thread context
 
3384
      table             - table list
 
3385
      lex_for_tmp_check - LEX of the query for which we are merging
 
3386
                          table list.
 
3387
 
 
3388
  NOTE
 
3389
    This method will use LEX provided to check whenever we are creating
 
3390
    temporary table and mark it as such in target multi-set.
 
3391
 
 
3392
  RETURN VALUE
 
3393
    TRUE  - Success
 
3394
    FALSE - Error
 
3395
*/
 
3396
 
 
3397
bool
 
3398
sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
 
3399
{
 
3400
  SP_TABLE *tab;
 
3401
 
 
3402
  if (lex_for_tmp_check->sql_command == SQLCOM_DROP_TABLE &&
 
3403
      lex_for_tmp_check->drop_temporary)
 
3404
    return TRUE;
 
3405
 
 
3406
  for (uint i= 0 ; i < m_sptabs.records ; i++)
 
3407
  {
 
3408
    tab= (SP_TABLE *)hash_element(&m_sptabs, i);
 
3409
    tab->query_lock_count= 0;
 
3410
  }
 
3411
 
 
3412
  for (; table ; table= table->next_global)
 
3413
    if (!table->derived && !table->schema_table)
 
3414
    {
 
3415
      char tname[(NAME_LEN + 1) * 3];           // db\0table\0alias\0
 
3416
      uint tlen, alen;
 
3417
 
 
3418
      tlen= table->db_length;
 
3419
      memcpy(tname, table->db, tlen);
 
3420
      tname[tlen++]= '\0';
 
3421
      memcpy(tname+tlen, table->table_name, table->table_name_length);
 
3422
      tlen+= table->table_name_length;
 
3423
      tname[tlen++]= '\0';
 
3424
      alen= strlen(table->alias);
 
3425
      memcpy(tname+tlen, table->alias, alen);
 
3426
      tlen+= alen;
 
3427
      tname[tlen]= '\0';
 
3428
 
 
3429
      /*
 
3430
        We ignore alias when we check if table was already marked as temporary
 
3431
        (and therefore should not be prelocked). Otherwise we will erroneously
 
3432
        treat table with same name but with different alias as non-temporary.
 
3433
      */
 
3434
      if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen)) ||
 
3435
          ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname,
 
3436
                                        tlen - alen - 1)) &&
 
3437
           tab->temp))
 
3438
      {
 
3439
        if (tab->lock_type < table->lock_type)
 
3440
          tab->lock_type= table->lock_type; // Use the table with the highest lock type
 
3441
        tab->query_lock_count++;
 
3442
        if (tab->query_lock_count > tab->lock_count)
 
3443
          tab->lock_count++;
 
3444
      }
 
3445
      else
 
3446
      {
 
3447
        if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE))))
 
3448
          return FALSE;
 
3449
        if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE &&
 
3450
            lex_for_tmp_check->query_tables == table &&
 
3451
            lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
3452
        {
 
3453
          tab->temp= TRUE;
 
3454
          tab->qname.length= tlen - alen - 1;
 
3455
        }
 
3456
        else
 
3457
          tab->qname.length= tlen;
 
3458
        tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1);
 
3459
        if (!tab->qname.str)
 
3460
          return FALSE;
 
3461
        tab->table_name_length= table->table_name_length;
 
3462
        tab->db_length= table->db_length;
 
3463
        tab->lock_type= table->lock_type;
 
3464
        tab->lock_count= tab->query_lock_count= 1;
 
3465
        my_hash_insert(&m_sptabs, (byte *)tab);
 
3466
      }
 
3467
    }
 
3468
  return TRUE;
 
3469
}
 
3470
 
 
3471
 
 
3472
/*
 
3473
  Add tables used by routine to the table list.
 
3474
 
 
3475
  SYNOPSIS
 
3476
    add_used_tables_to_table_list()
 
3477
      thd                    [in]     Thread context
 
3478
      query_tables_last_ptr  [in/out] Pointer to the next_global member of
 
3479
                                      last element of the list where tables
 
3480
                                      will be added (or to its root).
 
3481
      belong_to_view         [in]     Uppermost view which uses this routine,
 
3482
                                      0 if none.
 
3483
 
 
3484
  DESCRIPTION
 
3485
    Converts multi-set of tables used by this routine to table list and adds
 
3486
    this list to the end of table list specified by 'query_tables_last_ptr'.
 
3487
 
 
3488
    Elements of list will be allocated in PS memroot, so this list will be
 
3489
    persistent between PS executions.
 
3490
 
 
3491
  RETURN VALUE
 
3492
    TRUE - if some elements were added, FALSE - otherwise.
 
3493
*/
 
3494
 
 
3495
bool
 
3496
sp_head::add_used_tables_to_table_list(THD *thd,
 
3497
                                       TABLE_LIST ***query_tables_last_ptr,
 
3498
                                       TABLE_LIST *belong_to_view)
 
3499
{
 
3500
  uint i;
 
3501
  Query_arena *arena, backup;
 
3502
  bool result= FALSE;
 
3503
  DBUG_ENTER("sp_head::add_used_tables_to_table_list");
 
3504
 
 
3505
  /*
 
3506
    Use persistent arena for table list allocation to be PS/SP friendly.
 
3507
    Note that we also have to copy database/table names and alias to PS/SP
 
3508
    memory since current instance of sp_head object can pass away before
 
3509
    next execution of PS/SP for which tables are added to prelocking list.
 
3510
    This will be fixed by introducing of proper invalidation mechanism
 
3511
    once new TDC is ready.
 
3512
  */
 
3513
  arena= thd->activate_stmt_arena_if_needed(&backup);
 
3514
 
 
3515
  for (i=0 ; i < m_sptabs.records ; i++)
 
3516
  {
 
3517
    char *tab_buff, *key_buff;
 
3518
    TABLE_LIST *table;
 
3519
    SP_TABLE *stab= (SP_TABLE *)hash_element(&m_sptabs, i);
 
3520
    if (stab->temp)
 
3521
      continue;
 
3522
 
 
3523
    if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) *
 
3524
                                        stab->lock_count)) ||
 
3525
        !(key_buff= (char*)thd->memdup(stab->qname.str,
 
3526
                                       stab->qname.length + 1)))
 
3527
      DBUG_RETURN(FALSE);
 
3528
 
 
3529
    for (uint j= 0; j < stab->lock_count; j++)
 
3530
    {
 
3531
      table= (TABLE_LIST *)tab_buff;
 
3532
 
 
3533
      table->db= key_buff;
 
3534
      table->db_length= stab->db_length;
 
3535
      table->table_name= table->db + table->db_length + 1;
 
3536
      table->table_name_length= stab->table_name_length;
 
3537
      table->alias= table->table_name + table->table_name_length + 1;
 
3538
      table->lock_type= stab->lock_type;
 
3539
      table->cacheable_table= 1;
 
3540
      table->prelocking_placeholder= 1;
 
3541
      table->belong_to_view= belong_to_view;
 
3542
 
 
3543
      /* Everyting else should be zeroed */
 
3544
 
 
3545
      **query_tables_last_ptr= table;
 
3546
      table->prev_global= *query_tables_last_ptr;
 
3547
      *query_tables_last_ptr= &table->next_global;
 
3548
 
 
3549
      tab_buff+= ALIGN_SIZE(sizeof(TABLE_LIST));
 
3550
      result= TRUE;
 
3551
    }
 
3552
  }
 
3553
 
 
3554
  if (arena)
 
3555
    thd->restore_active_arena(arena, &backup);
 
3556
 
 
3557
  DBUG_RETURN(result);
 
3558
}
 
3559
 
 
3560
 
 
3561
/*
 
3562
  Simple function for adding an explicetly named (systems) table to
 
3563
  the global table list, e.g. "mysql", "proc".
 
3564
*/
 
3565
 
 
3566
TABLE_LIST *
 
3567
sp_add_to_query_tables(THD *thd, LEX *lex,
 
3568
                       const char *db, const char *name,
 
3569
                       thr_lock_type locktype)
 
3570
{
 
3571
  TABLE_LIST *table;
 
3572
 
 
3573
  if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
 
3574
  {
 
3575
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST));
 
3576
    return NULL;
 
3577
  }
 
3578
  table->db_length= strlen(db);
 
3579
  table->db= thd->strmake(db, table->db_length);
 
3580
  table->table_name_length= strlen(name);
 
3581
  table->table_name= thd->strmake(name, table->table_name_length);
 
3582
  table->alias= thd->strdup(name);
 
3583
  table->lock_type= locktype;
 
3584
  table->select_lex= lex->current_select; // QQ?
 
3585
  table->cacheable_table= 1;
 
3586
  
 
3587
  lex->add_to_query_tables(table);
 
3588
  return table;
 
3589
}
 
3590