Commit 902932a1 authored by unknown's avatar unknown
Browse files

Fixed BUG#13133: Local variables in stored procedures are not initialized correctly.

  Have to init. all local variables in their frames, not just once at the beginning
  of invocation.


mysql-test/r/sp.result:
  New test case for BUG#13133.
mysql-test/t/sp.test:
  New test case for BUG#13133.
sql/sp_head.cc:
  Just init. local variable slots in the fram to NULL. (Real init. will be done
  in each block.)
sql/sp_pcontext.cc:
  Removed isset flag, since it's not used.
sql/sp_pcontext.h:
  Removed isset flag, since it's not used.
sql/sql_yacc.yy:
  Initialize local variables in the block to null, or the default value, given.
  (Untabifed block too.)
parent b50eb4cd
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -3225,4 +3225,43 @@ select @var|
@var
abcdabcd
drop procedure bug12849_2|
drop procedure if exists bug131333|
drop function if exists bug131333|
create procedure bug131333()
begin
begin
declare a int;
select a;
set a = 1;
select a;
end;
begin
declare b int;
select b;
end;
end|
create function bug131333()
returns int
begin
begin
declare a int;
set a = 1;
end;
begin
declare b int;
return b;
end;
end|
call bug131333()|
a
NULL
a
1
b
NULL
select bug131333()|
bug131333()
NULL
drop procedure bug131333|
drop function bug131333|
drop table t1,t2;
+45 −0
Original line number Diff line number Diff line
@@ -4063,6 +4063,51 @@ call bug12849_2(@var)|
select @var|
drop procedure bug12849_2|

#
# BUG#13133: Local variables in stored procedures are not initialized correctly.
#
--disable_warnings
drop procedure if exists bug131333|
drop function if exists bug131333|
--enable_warnings
create procedure bug131333()
begin
  begin
    declare a int;

    select a;
    set a = 1;
    select a;
  end;
  begin
    declare b int;

    select b;
  end;
end|

create function bug131333()
  returns int
begin
  begin
    declare a int;

    set a = 1;
  end;
  begin
    declare b int;

    return b;
  end;
end|

call bug131333()|
select bug131333()|

drop procedure bug131333|
drop function bug131333|


#
# BUG#NNNN: New bug synopsis
#
+9 −26
Original line number Diff line number Diff line
@@ -1078,7 +1078,6 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
  sp_rcontext *octx = thd->spcont;
  sp_rcontext *nctx = NULL;
  uint i;
  Item_null *nit;
  int ret= -1;                                  // Assume error

  if (argcount != params)
@@ -1109,22 +1108,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
    nctx->push_item(it);
  }


  /*
    The rest of the frame are local variables which are all IN.
    Default all variables to null (those with default clauses will
    be set by an set instruction).
    Push NULLs to get the right size (and make the reuse mechanism work) -
    the will be initialized by set instructions in each frame.
  */

  nit= NULL;                       // Re-use this, and only create if needed
  for (; i < csize ; i++)
  {
    if (! nit)
    {
      if (!(nit= new Item_null()))
        DBUG_RETURN(-1);
    }
    nctx->push_item(nit);
  }
    nctx->push_item(NULL);

  thd->spcont= nctx;

  binlog_save_options= thd->options;
@@ -1321,23 +1313,14 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
      close_thread_tables(thd, 0, 0);

    DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str));

    /*
      The rest of the frame are local variables which are all IN.
      Default all variables to null (those with default clauses will
      be set by an set instruction).
      Push NULLs to get the right size (and make the reuse mechanism work) -
      the will be initialized by set instructions in each frame.
    */
    for (; i < csize ; i++)
    {
      if (! nit)
      {
	if (!(nit= new Item_null()))
        {
          ret= -1;
          break;
        }
      }
      nctx->push_item(nit);
    }
      nctx->push_item(NULL);
  }

  thd->spcont= nctx;
+0 −1
Original line number Diff line number Diff line
@@ -184,7 +184,6 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
    p->type= type;
    p->mode= mode;
    p->offset= current_pvars();
    p->isset= (mode == sp_param_out ? FALSE : TRUE);
    p->dflt= NULL;
    insert_dynamic(&m_pvar, (gptr)&p);
  }
+0 −10
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ typedef struct sp_pvar
  enum enum_field_types type;
  sp_param_mode_t mode;
  uint offset;			// Offset in current frame
  my_bool isset;
  Item *dflt;
} sp_pvar_t;

@@ -147,15 +146,6 @@ class sp_pcontext : public Sql_alloc
      p->type= type;
  }

  inline void
  set_isset(uint i, my_bool val)
  {
    sp_pvar_t *p= find_pvar(i);

    if (p)
      p->isset= val;
  }

  inline void
  set_default(uint i, Item *it)
  {
Loading