• unknown's avatar
    Fix for bug #5888 "Triggers with nonexistent columns cause packets · c3da2d12
    unknown authored
    out of order". (final version)
    
    Now instead of binding Item_trigger_field to TABLE objects during
    trigger definition parsing at table open, we perform pass through
    special list of all such objects in trigger. This allows easily check
    all references to fields in old/new version of row in trigger during
    execution of CREATE TRIGGER statement (this is more courtesy for users
    since we can't check everything anyway).
    We also report that such reference is bad by returning error from
    Item_trigger_field::fix_fields() method (instead of setup_field())
    This means that if trigger is broken we will bark during trigger
    execution instead of trigger definition parsing at table open.
    (i.e. now we allow to open tables with broken triggers).
    
    
    mysql-test/r/trigger.result:
      Added test which attempts to create trigger for table referencing to
      field which does not exist in this table.
    mysql-test/t/trigger.test:
      Added test which attempts to create trigger for table referencing to
      field which does not exist in this table.
    sql/item.cc:
      Item_trigger_field::setup_field() now returns void. If any error
      will occur we will report it at fix_fields() stage.
    sql/item.h:
      Item_trigger_field:
      - Added next_trg_field member for linking all such objects in trigger
        in one list.
      - Also setup_field() now returns void. If any error will occur we will
        report it at fix_fields() stage.
    sql/mysql_priv.h:
      Added SQL_LIST::push_back() method which allows to add another SQL_LIST
      to the end of this SQL_LIST.
    sql/sp_head.cc:
      sp_head::init()/reset_lex()/restore_lex():
       In order to fill global LEX::trg_table_fields (list of all 
       Item_trigger_field objects for trigger) we should init the same list
       in LEX of substatement before its parsing and merge it to global list
       after parsing.
    sql/sp_head.h:
      sp_instr_trigger_field:
        Made trigger_field member public to be able to add it more easily to
        global list of all Item_trigger_field objects in trigger.
    sql/sql_lex.cc:
      LEX::trg_table was removed.
    sql/sql_lex.h:
      Now we are binding Item_trigger_field's to TABLE object by passing
      through specially constructed list of all such objects in this trigger
      instead of doing this during trigger definition parsing at table open.
      So we no longer need LEX::trg_table, we use LEX::trg_table_fields list
      instead.
    sql/sql_parse.cc:
      mysql_execute_command():
        Since now we use trigger body for some checks in
        mysql_create_or_drop_trigger() we should destroy it only
        after calling this function.
    sql/sql_trigger.cc:
      Now instead of binding Item_trigger_field to TABLE objects during
      trigger definition parsing at table open, we perform pass through
      special list of all such objects in trigger. This allows easily check
      all references to fields in old/new version of row in trigger during
      execution of CREATE TRIGGER statement (this is more courtesy for users
      since we can't check everything anyway).
      We also report that such reference is bad by returning error from
      Item_trigger_field::fix_fields() method (instead of setup_field())
      This means that if trigger is broken we will bark during trigger
      execution instead of trigger definition parsing at table open.
      (i.e. now we allow to open tables with broken triggers).
      
      Table_triggers_list::prepare_old_row_accessors() method was added to be
      able to reuse code creating Field objects referencing TABLE::record[1]
      buffer instead of TABLE::record[0].
    sql/sql_trigger.h:
      Added Table_triggers_list::prepare_old_row_accessors() method to be
      able to reuse code creating Field objects referencing to TABLE::record[1]
      instead of record[0].
    sql/sql_yacc.yy:
      Now instead of performing binding of Item_trigger_field objects
      to TABLE object during trigger definition parsing at table open,
      we perform this binding by passing through specially constructed
      list of all such items in trigger.
      We also check value returned from memory allocation functions.
    c3da2d12
mysql_priv.h 52.2 KB