bool LEX::sp_for_loop_cursor_declarations(THD *thd,
                                          Lex_for_loop_st *loop,
                                          const LEX_CSTRING *index,
                                          const Lex_for_loop_bounds_st &bounds)
{
  Item *item= bounds.m_index->get_item();
  Item_splocal *item_splocal;
  Item_field *item_field;
  Item_func_sp *item_func_sp= NULL;
  LEX_CSTRING name;
  uint coffs, param_count= 0;
  const sp_pcursor *pcursor;
  DBUG_ENTER("LEX::sp_for_loop_cursor_declarations");

  if ((item_splocal= item->get_item_splocal()))
    name= item_splocal->m_name;
  else if ((item_field= item->type() == Item::FIELD_ITEM ?
                        static_cast<Item_field *>(item) : NULL) &&
           item_field->table_name == NULL)
    name= item_field->field_name;
  else if (item->type() == Item::FUNC_ITEM &&
           static_cast<Item_func*>(item)->functype() == Item_func::FUNC_SP &&
           !static_cast<Item_func_sp*>(item)->get_sp_name()->m_explicit_name)
  {
    /*
      When a FOR LOOP for a cursor with parameters is parsed:
        FOR index IN cursor(1,2,3) LOOP
          statements;
        END LOOP;
      the parser scans "cursor(1,2,3)" using the "expr" rule,
      so it thinks that cursor(1,2,3) is a stored function call.
      It's not easy to implement this without using "expr" because
      of grammar conflicts.
      As a side effect, the Item_func_sp and its arguments in the parentheses
      belong to the same LEX. This is different from an explicit
      "OPEN cursor(1,2,3)" where every expression belongs to a separate LEX.
    */
    item_func_sp= static_cast<Item_func_sp*>(item);
    name= item_func_sp->get_sp_name()->m_name;
    param_count= item_func_sp->argument_count();
  }
  else
  {
    thd->parse_error();
    DBUG_RETURN(true);
  }
  if (unlikely(!(pcursor= spcont->find_cursor_with_error(&name, &coffs,
                                                         false)) ||
               pcursor->check_param_count_with_error(param_count)))
    DBUG_RETURN(true);

  if (!(loop->m_index= sp_add_for_loop_cursor_variable(thd, index,
                                                       pcursor, coffs,
                                                       bounds.m_index,
                                                       item_func_sp)))
    DBUG_RETURN(true);
  loop->m_target_bound= NULL;
  loop->m_direction= bounds.m_direction;
  loop->m_cursor_offset= coffs;
  loop->m_implicit_cursor= bounds.m_implicit_cursor;
  DBUG_RETURN(false);
}
bool LEX::sp_for_loop_cursor_declarations(THD *thd,
                                          Lex_for_loop_st *loop,
                                          const LEX_CSTRING *index,
                                          const Lex_for_loop_bounds_st &bounds)
{
  Item *item= bounds.m_index->get_item();
  Item_splocal *item_splocal;
  Item_field *item_field;
  Item_func_sp *item_func_sp= NULL;
  LEX_CSTRING name;
  uint coffs, param_count= 0;
  const sp_pcursor *pcursor;
  DBUG_ENTER("LEX::sp_for_loop_cursor_declarations");

  if ((item_splocal= item->get_item_splocal()))
    name= item_splocal->m_name;
  else if ((item_field= item->type() == Item::FIELD_ITEM ?
                        static_cast<Item_field *>(item) : NULL) &&
           item_field->table_name == NULL)
    name= item_field->field_name;
  else if (item->type() == Item::FUNC_ITEM &&
           static_cast<Item_func*>(item)->functype() == Item_func::FUNC_SP &&
           !static_cast<Item_func_sp*>(item)->get_sp_name()->m_explicit_name)
  {
     
    item_func_sp= static_cast<Item_func_sp*>(item);
    name= item_func_sp->get_sp_name()->m_name;
    param_count= item_func_sp->argument_count();
  }
  else
  {
    thd->parse_error();
    DBUG_RETURN(true);
  }
  if (unlikely(!(pcursor= spcont->find_cursor_with_error(&name, &coffs,
                                                         false)) ||
               pcursor->check_param_count_with_error(param_count)))
    DBUG_RETURN(true);

  if (!(loop->m_index= sp_add_for_loop_cursor_variable(thd, index,
                                                       pcursor, coffs,
                                                       bounds.m_index,
                                                       item_func_sp)))
    DBUG_RETURN(true);
  loop->m_target_bound= NULL;
  loop->m_direction= bounds.m_direction;
  loop->m_cursor_offset= coffs;
  loop->m_implicit_cursor= bounds.m_implicit_cursor;
  DBUG_RETURN(false);
}