~mdcallag/+junk/5.1-map

« back to all changes in this revision

Viewing changes to sql/item_func.cc

  • Committer: msvensson at pilot
  • Date: 2007-04-24 09:11:45 UTC
  • mfrom: (2469.1.106)
  • Revision ID: sp1r-msvensson@pilot.blaudden-20070424091145-10463
Merge pilot.blaudden:/home/msvensson/mysql/my51-m-mysql_upgrade
into  pilot.blaudden:/home/msvensson/mysql/mysql-5.1-maint

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
#include "mysql_priv.h"
24
24
#include "slave.h"                              // for wait_for_master_pos
 
25
#include "rpl_mi.h"
25
26
#include <m_ctype.h>
26
27
#include <hash.h>
27
28
#include <time.h>
413
414
  if (item->type() != FUNC_ITEM)
414
415
    return 0;
415
416
  Item_func *item_func=(Item_func*) item;
416
 
  if (arg_count != item_func->arg_count ||
417
 
      func_name() != item_func->func_name())
 
417
  Item_func::Functype func_type;
 
418
  if ((func_type= functype()) != item_func->functype() ||
 
419
      arg_count != item_func->arg_count ||
 
420
      (func_type != Item_func::FUNC_SP &&
 
421
       func_name() != item_func->func_name()) ||
 
422
      (func_type == Item_func::FUNC_SP &&
 
423
       my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
418
424
    return 0;
419
425
  for (uint i=0; i < arg_count ; i++)
420
426
    if (!args[i]->eq(item_func->args[i], binary_cmp))
430
436
 
431
437
  switch (result_type()) {
432
438
  case INT_RESULT:
433
 
    if (max_length > 11)
 
439
    if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
434
440
      field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
435
441
    else
436
442
      field= new Field_long(max_length, maybe_null, name, unsigned_flag);
2333
2339
 
2334
2340
void Item_func_locate::fix_length_and_dec()
2335
2341
{
2336
 
  maybe_null=0; max_length=11;
 
2342
  maybe_null= 0;
 
2343
  max_length= MY_INT32_NUM_DECIMAL_DIGITS;
2337
2344
  agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
2338
2345
}
2339
2346
 
4602
4609
    fields.push_back(new Item_string(" ",1, cmp_collation.collation));
4603
4610
    for (uint i=1; i < arg_count; i++)
4604
4611
      fields.push_back(args[i]);
4605
 
    concat=new Item_func_concat_ws(fields);
 
4612
    concat_ws=new Item_func_concat_ws(fields);
4606
4613
    /*
4607
4614
      Above function used only to get value and do not need fix_fields for it:
4608
4615
      Item_string - basic constant
4609
4616
      fields - fix_fields() was already called for this arguments
4610
4617
      Item_func_concat_ws - do not need fix_fields() to produce value
4611
4618
    */
4612
 
    concat->quick_fix_field();
 
4619
    concat_ws->quick_fix_field();
4613
4620
  }
4614
4621
 
4615
4622
  if (master)
4824
4831
 
4825
4832
  if (key == NO_SUCH_KEY)
4826
4833
  {
4827
 
    String *a= concat->val_str(&value);
4828
 
    if ((null_value= (a == 0)))
 
4834
    String *a= concat_ws->val_str(&value);
 
4835
    if ((null_value= (a == 0)) || !a->length())
4829
4836
      DBUG_RETURN(0);
4830
4837
    DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
4831
4838
                                      (byte *)a->ptr(), a->length()));
4982
4989
}
4983
4990
 
4984
4991
 
4985
 
Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
4986
 
                           sp_name *name_arg)
4987
 
  :Item_func(), context(context_arg), m_name(name_arg), m_sp(NULL),
4988
 
   result_field(NULL)
 
4992
 
 
4993
 
 
4994
Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name)
 
4995
  :Item_func(), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL)
4989
4996
{
4990
4997
  maybe_null= 1;
4991
4998
  m_name->init_qname(current_thd);
4995
5002
 
4996
5003
 
4997
5004
Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
4998
 
                           sp_name *name_arg, List<Item> &list)
4999
 
  :Item_func(list), context(context_arg), m_name(name_arg), m_sp(NULL),
5000
 
   result_field(NULL)
 
5005
                           sp_name *name, List<Item> &list)
 
5006
  :Item_func(list), context(context_arg), m_name(name), m_sp(NULL),sp_result_field(NULL)
5001
5007
{
5002
5008
  maybe_null= 1;
5003
5009
  m_name->init_qname(current_thd);
5009
5015
void
5010
5016
Item_func_sp::cleanup()
5011
5017
{
5012
 
  if (result_field)
 
5018
  if (sp_result_field)
5013
5019
  {
5014
 
    delete result_field;
5015
 
    result_field= NULL;
 
5020
    delete sp_result_field;
 
5021
    sp_result_field= NULL;
5016
5022
  }
5017
5023
  m_sp= NULL;
5018
5024
  dummy_table->alias= NULL;
5024
5030
{
5025
5031
  THD *thd= current_thd;
5026
5032
  /* Calculate length to avoid reallocation of string for sure */
5027
 
  uint len= ((m_name->m_db.length +
 
5033
  uint len= ((m_name->m_explicit_name ? m_name->m_db.length : 0 +
5028
5034
              m_name->m_name.length)*2 + //characters*quoting
5029
5035
             2 +                         // ` and `
5030
5036
             1 +                         // .
5034
5040
               system_charset_info);
5035
5041
 
5036
5042
  qname.length(0);
5037
 
  append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length);
5038
 
  qname.append('.');
 
5043
  if (m_name->m_explicit_name)
 
5044
  {
 
5045
    append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length);
 
5046
    qname.append('.');
 
5047
  }
5039
5048
  append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length);
5040
5049
  return qname.ptr();
5041
5050
}
5042
5051
 
5043
5052
 
5044
 
Field *
5045
 
Item_func_sp::sp_result_field(void) const
5046
 
{
5047
 
  Field *field;
5048
 
  DBUG_ENTER("Item_func_sp::sp_result_field");
5049
 
  DBUG_PRINT("info", ("sp: %s, flags: %x, level: %lu",
5050
 
                      (m_sp ? "YES" : "NO"),
5051
 
                      (m_sp ? m_sp->m_flags : (uint)0),
5052
 
                      (m_sp ? m_sp->m_recursion_level : (ulong)0)));
5053
 
 
5054
 
  if (!m_sp)
5055
 
  {
5056
 
    THD *thd= current_thd;
5057
 
    if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
5058
 
                                &thd->sp_func_cache, TRUE)))
5059
 
    {
5060
 
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
5061
 
      DBUG_RETURN(0);
5062
 
    }
5063
 
  }
5064
 
  if (!dummy_table->alias)
5065
 
  {
5066
 
    char *empty_name= (char *) "";
5067
 
    dummy_table->alias= empty_name;
5068
 
    dummy_table->maybe_null= maybe_null;
5069
 
    dummy_table->in_use= current_thd;
5070
 
    dummy_table->copy_blobs= TRUE;
5071
 
    dummy_table->s->table_cache_key.str = empty_name;
5072
 
    dummy_table->s->table_name.str= empty_name;
5073
 
    dummy_table->s->db.str= empty_name;
5074
 
  }
5075
 
  if (!(field= m_sp->create_result_field(max_length, name, dummy_table)))
5076
 
    my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
5077
 
 
5078
 
  DBUG_RETURN(field);
5079
 
}
5080
 
 
5081
 
 
5082
 
/*
5083
 
  Execute function & store value in field
5084
 
 
5085
 
  RETURN
5086
 
   0  value <> NULL
5087
 
   1  value =  NULL  or error
5088
 
*/
5089
 
 
5090
 
bool
5091
 
Item_func_sp::execute(Field **flp)
 
5053
 
 
5054
/**
 
5055
  @brief Initialize the result field by creating a temporary dummy table
 
5056
    and assign it to a newly created field object. Meta data used to
 
5057
    create the field is fetched from the sp_head belonging to the stored
 
5058
    proceedure found in the stored procedure functon cache.
 
5059
  
 
5060
  @note This function should be called from fix_fields to init the result
 
5061
    field. It is some what related to Item_field.
 
5062
 
 
5063
  @see Item_field
 
5064
 
 
5065
  @param thd A pointer to the session and thread context.
 
5066
 
 
5067
  @return Function return error status.
 
5068
  @retval TRUE is returned on an error
 
5069
  @retval FALSE is returned on success.
 
5070
*/
 
5071
bool
 
5072
Item_func_sp::init_result_field(THD *thd)
 
5073
{
 
5074
  DBUG_ENTER("Item_func_sp::init_result_field");
 
5075
 
 
5076
  LEX_STRING empty_name= { C_STRING_WITH_LEN("") };
 
5077
  
 
5078
  TABLE_SHARE *share;
 
5079
 
 
5080
  DBUG_ASSERT(m_sp == NULL);
 
5081
  DBUG_ASSERT(sp_result_field == NULL);
 
5082
 
 
5083
  if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
 
5084
                               &thd->sp_func_cache, TRUE)))
 
5085
  {
 
5086
    my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
 
5087
    context->process_error(thd);
 
5088
    DBUG_RETURN(TRUE);
 
5089
  }
 
5090
 
 
5091
  /*
 
5092
     A Field need to be attached to a Table.
 
5093
     Below we "create" a dummy table by initializing 
 
5094
     the needed pointers.
 
5095
   */
 
5096
  
 
5097
  share= dummy_table->s;
 
5098
  dummy_table->alias = "";
 
5099
  dummy_table->maybe_null = maybe_null;
 
5100
  dummy_table->in_use= thd;
 
5101
  dummy_table->copy_blobs= TRUE;
 
5102
  share->table_cache_key = empty_name;
 
5103
  share->table_name = empty_name;
 
5104
 
 
5105
  if (!(sp_result_field= m_sp->create_result_field(max_length, name, dummy_table)))
 
5106
  {
 
5107
   DBUG_RETURN(TRUE);
 
5108
  }
 
5109
  
 
5110
  if (sp_result_field->pack_length() > sizeof(result_buf))
 
5111
  {
 
5112
    sp_result_field->move_field(sql_alloc(sp_result_field->pack_length()));
 
5113
  } else {
 
5114
    sp_result_field->move_field(result_buf);
 
5115
  }
 
5116
  
 
5117
  sp_result_field->null_ptr= (uchar *) &null_value;
 
5118
  sp_result_field->null_bit= 1;
 
5119
  
 
5120
 
 
5121
  DBUG_RETURN(FALSE);
 
5122
}
 
5123
 
 
5124
/**
 
5125
  @brief Initialize local members with values from the Field interface.
 
5126
 
 
5127
  @note called from Item::fix_fields.
 
5128
*/
 
5129
void Item_func_sp::fix_length_and_dec()
 
5130
{
 
5131
  DBUG_ENTER("Item_func_sp::fix_length_and_dec");
 
5132
 
 
5133
  DBUG_ASSERT(sp_result_field);
 
5134
  decimals= sp_result_field->decimals();
 
5135
  max_length= sp_result_field->field_length;
 
5136
  collation.set(sp_result_field->charset());
 
5137
  maybe_null= 1;
 
5138
  unsigned_flag= test(sp_result_field->flags & UNSIGNED_FLAG);
 
5139
 
 
5140
  DBUG_VOID_RETURN;
 
5141
}
 
5142
 
 
5143
/**
 
5144
  @brief Execute function & store value in field.
 
5145
 
 
5146
  @return Function returns error status.
 
5147
  @retval FALSE on success.
 
5148
  @retval TRUE if an error occurred.
 
5149
*/
 
5150
 
 
5151
bool
 
5152
Item_func_sp::execute()
5092
5153
{
5093
5154
  THD *thd= current_thd;
5094
 
  Field *f;
5095
 
 
 
5155
  
5096
5156
  /*
5097
5157
    Get field in virtual tmp table to store result. Create the field if
5098
5158
    invoked first time.
5099
5159
  */
5100
 
  
5101
 
  if (!(f= *flp))
5102
 
  {
5103
 
    if (!(*flp= f= sp_result_field()))
5104
 
    {
5105
 
      /* Error set by sp_result_field() */
5106
 
      null_value= 1;
5107
 
      return TRUE;
5108
 
    }
5109
5160
 
5110
 
    f->move_field((f->pack_length() > sizeof(result_buf)) ?
5111
 
                  sql_alloc(f->pack_length()) : result_buf);
5112
 
    f->null_ptr= (uchar *)&null_value;
5113
 
    f->null_bit= 1;
5114
 
  }
5115
5161
 
5116
5162
  /* Execute function and store the return value in the field. */
5117
5163
 
5118
 
  if (execute_impl(thd, f))
 
5164
  if (execute_impl(thd))
5119
5165
  {
5120
5166
    null_value= 1;
5121
5167
    context->process_error(thd);
5124
5170
 
5125
5171
  /* Check that the field (the value) is not NULL. */
5126
5172
 
5127
 
  null_value= f->is_null();
 
5173
  null_value= sp_result_field->is_null();
5128
5174
 
5129
5175
  return null_value;
5130
5176
}
5131
5177
 
5132
5178
 
 
5179
/**
 
5180
   @brief Execute function and store the return value in the field.
 
5181
 
 
5182
   @note This function was intended to be the concrete implementation of
 
5183
    the interface function execute. This was never realized.
 
5184
 
 
5185
   @return The error state.
 
5186
   @retval FALSE on success
 
5187
   @retval TRUE if an error occurred.
 
5188
*/
5133
5189
bool
5134
 
Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
 
5190
Item_func_sp::execute_impl(THD *thd)
5135
5191
{
5136
5192
  bool err_status= TRUE;
5137
5193
  Sub_statement_state statement_state;
5148
5204
    thd->security_ctx= context->security_ctx;
5149
5205
  }
5150
5206
#endif
5151
 
  if (find_and_check_access(thd))
 
5207
  if (sp_check_access(thd))
5152
5208
    goto error;
5153
5209
 
5154
5210
  /*
5169
5225
    function call into binlog.
5170
5226
  */
5171
5227
  thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
5172
 
  err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld);
 
5228
  err_status= m_sp->execute_function(thd, args, arg_count, sp_result_field); 
5173
5229
  thd->restore_sub_statement_state(&statement_state);
5174
5230
 
5175
5231
error:
5184
5240
void
5185
5241
Item_func_sp::make_field(Send_field *tmp_field)
5186
5242
{
5187
 
  Field *field;
5188
5243
  DBUG_ENTER("Item_func_sp::make_field");
5189
 
  if ((field= sp_result_field()))
5190
 
  {
5191
 
    field->make_field(tmp_field);
5192
 
    delete field;
5193
 
    DBUG_VOID_RETURN;
5194
 
  }
5195
 
  init_make_field(tmp_field, MYSQL_TYPE_VARCHAR);  
 
5244
  DBUG_ASSERT(sp_result_field);
 
5245
  sp_result_field->make_field(tmp_field);
5196
5246
  DBUG_VOID_RETURN;
5197
5247
}
5198
5248
 
5200
5250
enum enum_field_types
5201
5251
Item_func_sp::field_type() const
5202
5252
{
5203
 
  Field *field;
5204
5253
  DBUG_ENTER("Item_func_sp::field_type");
5205
 
 
5206
 
  if (result_field)
5207
 
    DBUG_RETURN(result_field->type());
5208
 
  if ((field= sp_result_field()))
5209
 
  {
5210
 
    enum_field_types result= field->type();
5211
 
    delete field;
5212
 
    DBUG_RETURN(result);
5213
 
  }
5214
 
  DBUG_RETURN(MYSQL_TYPE_VARCHAR);
 
5254
  DBUG_ASSERT(sp_result_field);
 
5255
  DBUG_RETURN(sp_result_field->type());
5215
5256
}
5216
5257
 
5217
 
 
5218
5258
Item_result
5219
5259
Item_func_sp::result_type() const
5220
5260
{
5221
 
  Field *field;
5222
5261
  DBUG_ENTER("Item_func_sp::result_type");
5223
 
  DBUG_PRINT("info", ("m_sp: 0x%lx", (long) m_sp));
5224
 
 
5225
 
  if (result_field)
5226
 
    DBUG_RETURN(result_field->result_type());
5227
 
  if ((field= sp_result_field()))
5228
 
  {
5229
 
    Item_result result= field->result_type();
5230
 
    delete field;
5231
 
    DBUG_RETURN(result);
5232
 
  }
5233
 
  DBUG_RETURN(STRING_RESULT);
5234
 
}
5235
 
 
5236
 
void
5237
 
Item_func_sp::fix_length_and_dec()
5238
 
{
5239
 
  Field *field;
5240
 
  DBUG_ENTER("Item_func_sp::fix_length_and_dec");
5241
 
 
5242
 
  if (result_field)
5243
 
  {
5244
 
    decimals= result_field->decimals();
5245
 
    max_length= result_field->field_length;
5246
 
    collation.set(result_field->charset());
5247
 
    DBUG_VOID_RETURN;
5248
 
  }
5249
 
 
5250
 
  if (!(field= sp_result_field()))
5251
 
  {
5252
 
    context->process_error(current_thd);
5253
 
    DBUG_VOID_RETURN;
5254
 
  }
5255
 
  decimals= field->decimals();
5256
 
  max_length= field->field_length;
5257
 
  collation.set(field->charset());
5258
 
  maybe_null= 1;
5259
 
  delete field;
5260
 
  DBUG_VOID_RETURN;
5261
 
}
5262
 
 
 
5262
  DBUG_PRINT("info", ("m_sp = %p", m_sp));
 
5263
  DBUG_ASSERT(sp_result_field);
 
5264
  DBUG_RETURN(sp_result_field->result_type());
 
5265
}
5263
5266
 
5264
5267
longlong Item_func_found_rows::val_int()
5265
5268
{
5271
5274
Field *
5272
5275
Item_func_sp::tmp_table_field(TABLE *t_arg)
5273
5276
{
5274
 
  Field *field= 0;
5275
5277
  DBUG_ENTER("Item_func_sp::tmp_table_field");
5276
5278
 
5277
 
  if (m_sp)
5278
 
    field= m_sp->create_result_field(max_length, (const char*) name, t_arg);
5279
 
  
5280
 
  if (!field) 
5281
 
    field= Item_func::tmp_table_field(t_arg);
5282
 
 
5283
 
  if (!field)
5284
 
    my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
5285
 
 
5286
 
  DBUG_RETURN(field);
 
5279
  DBUG_ASSERT(sp_result_field);
 
5280
  DBUG_RETURN(sp_result_field);
5287
5281
}
5288
5282
 
5289
5283
 
5290
 
/*
5291
 
  Find the function and check access rights to the function
5292
 
 
5293
 
  SYNOPSIS
5294
 
    find_and_check_access()
5295
 
    thd           thread handler
5296
 
 
5297
 
  RETURN
5298
 
    FALSE    Access granted
5299
 
    TRUE     Requested access can't be granted or function doesn't exists
5300
 
 
5301
 
  NOTES
5302
 
    Checks if requested access to function can be granted to user.
 
5284
/**
 
5285
  @brief Checks if requested access to function can be granted to user.
5303
5286
    If function isn't found yet, it searches function first.
5304
5287
    If function can't be found or user don't have requested access
5305
5288
    error is raised.
 
5289
 
 
5290
  @param thd thread handler
 
5291
 
 
5292
  @return Indication if the access was granted or not.
 
5293
  @retval FALSE Access is granted.
 
5294
  @retval TRUE Requested access can't be granted or function doesn't exists.
 
5295
    
5306
5296
*/
5307
5297
 
5308
5298
bool
5309
 
Item_func_sp::find_and_check_access(THD *thd)
 
5299
Item_func_sp::sp_check_access(THD *thd)
5310
5300
{
5311
 
  if (! m_sp && ! (m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
5312
 
                                         &thd->sp_func_cache, TRUE)))
5313
 
  {
5314
 
    my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
5315
 
    return TRUE;
5316
 
  }
5317
 
 
 
5301
  DBUG_ENTER("Item_func_sp::sp_check_access");
 
5302
  DBUG_ASSERT(m_sp);
5318
5303
#ifndef NO_EMBEDDED_ACCESS_CHECKS
5319
5304
  if (check_routine_access(thd, EXECUTE_ACL,
5320
5305
                           m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
5321
 
    return TRUE;
 
5306
    DBUG_RETURN(TRUE);
5322
5307
#endif
5323
5308
 
5324
 
  return FALSE;
 
5309
  DBUG_RETURN(FALSE);
5325
5310
}
5326
5311
 
5327
5312
 
5329
5314
Item_func_sp::fix_fields(THD *thd, Item **ref)
5330
5315
{
5331
5316
  bool res;
 
5317
  DBUG_ENTER("Item_func_sp::fix_fields");
5332
5318
  DBUG_ASSERT(fixed == 0);
 
5319
 
 
5320
  /*
 
5321
    We must call init_result_field before Item_func::fix_fields() 
 
5322
    to make m_sp and result_field members available to fix_length_and_dec(),
 
5323
    which is called from Item_func::fix_fields().
 
5324
  */
 
5325
  res= init_result_field(thd);
 
5326
 
 
5327
  if (res)
 
5328
    DBUG_RETURN(res);
 
5329
 
5333
5330
  res= Item_func::fix_fields(thd, ref);
5334
 
  if (!res && thd->lex->view_prepare_mode)
 
5331
 
 
5332
  if (res)
 
5333
    DBUG_RETURN(res);
 
5334
 
 
5335
  if (thd->lex->view_prepare_mode)
5335
5336
  {
5336
5337
    /*
5337
5338
      Here we check privileges of the stored routine only during view
5343
5344
      good idea especially if the view has SQL SECURITY DEFINER and
5344
5345
      the used stored procedure has SQL SECURITY DEFINER.
5345
5346
    */
5346
 
    res= find_and_check_access(thd);
 
5347
    res= sp_check_access(thd);
5347
5348
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
5349
    /*
 
5350
      Try to set and restore the security context to see whether it's valid
 
5351
    */
5348
5352
    Security_context *save_secutiry_ctx;
5349
 
    if (!res && !(res= set_routine_security_ctx(thd, m_sp, false,
5350
 
                                                &save_secutiry_ctx)))
5351
 
    {
5352
 
      sp_restore_security_context(thd, save_secutiry_ctx);
5353
 
    }
 
5353
    res= set_routine_security_ctx(thd, m_sp, false, &save_secutiry_ctx);
 
5354
    if (!res)
 
5355
      m_sp->m_security_ctx.restore_security_context(thd, save_secutiry_ctx);
 
5356
    
5354
5357
#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
5355
5358
  }
5356
 
  return res;
 
5359
  DBUG_RETURN(res);
5357
5360
}