← Back to team overview

maria-developers team mailing list archive

Re: 96569b793a3: MDEV-19761 - Before Trigger not processed for Not Null Column

 

Hi, Anel!

On Oct 29, Anel Husakovic wrote:
> revision-id: 96569b793a3 (mariadb-10.1.39-121-g96569b793a3)
> parent(s): e32f29b7f31
> author: Anel Husakovic <anel@xxxxxxxxxxx>
> committer: Anel Husakovic <anel@xxxxxxxxxxx>
> timestamp: 2019-07-24 23:50:29 -0700
> message:
> 
> MDEV-19761 - Before Trigger not processed for Not Null Column

here you should have a commit comment explaining the bug and your
solution.

> ---
>  mysql-test/r/trigger.result                      |  6 +++-
>  mysql-test/r/trigger_no_defaults-11698.result    | 29 +++++++++++++++++++
>  mysql-test/r/trigger_null-8605.result            |  2 +-
>  mysql-test/suite/funcs_1/r/innodb_trig_09.result |  4 +--
>  mysql-test/suite/funcs_1/r/memory_trig_09.result |  4 +--
>  mysql-test/suite/funcs_1/r/myisam_trig_09.result |  4 +--
>  mysql-test/t/trigger_no_defaults-11698.test      | 37 ++++++++++++++++++++----
>  sql/sql_base.cc                                  | 23 +++++++++++++++
>  sql/sql_trigger.cc                               |  2 +-
>  sql/sql_trigger.h                                |  4 +++
>  10 files changed, 97 insertions(+), 18 deletions(-)
> 
> diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
> index 8852a622251..04bb9d9be68 100644
> --- a/mysql-test/r/trigger.result
> +++ b/mysql-test/r/trigger.result
> @@ -366,6 +366,8 @@ create trigger trg1 before update on t1 for each row set @a:= @a + new.j - old.j
>  create trigger trg2 after update on t1 for each row set @b:= "Fired";
>  set @a:= 0, @b:= "";
>  update t1, t2 set j = j + 10 where t1.i = t2.i;
> +Warnings:
> +Warning	1048	Column 'k' cannot be null

this looks wrong. Why there's suddenly a warning here?

>  select @a, @b;
>  @a	@b
>  10	Fired
> @@ -1235,11 +1237,13 @@ insert into t1 values (1,1), (2,2), (3,3);
>  create trigger t1_bu before update on t1 for each row
>  set new.j = new.j + 10;
>  update t1 set i= i+ 10 where j > 2;
> +Warnings:
> +Warning	1048	Column 'j' cannot be null

and here

>  select * from t1;
> diff --git a/sql/sql_base.cc b/sql/sql_base.cc
> index e8bdff8b48f..d9fe37c83da 100644
> --- a/sql/sql_base.cc
> +++ b/sql/sql_base.cc
> @@ -8959,6 +8959,29 @@ void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *table)
>  
>      while ((item= it++))
>        item->walk(&Item::switch_to_nullable_fields_processor, 1, (uchar*)field);
> +    uint16 cnt=0;
> +    uchar *nptr;
> +    nptr= (uchar*)alloc_root(&table->mem_root, (table->s->fields - table->s->null_fields + 7)/8);
> +    // First find null_ptr for NULL field in case of mixed NULL and NOT NULL fields
> +    for (Field **f= field; *f; f++)
> +    {
> +      if (table->field[cnt]->null_ptr)
> +      {
> +        nptr= table->field[cnt]->null_ptr;
> +        break;
> +      }
> +    }
> +    for (Field **f= field; *f; f++)
> +    {
> +        if (!table->field[cnt]->null_ptr)
> +        {
> +          (*f)->null_bit= 1<<(cnt+1);
> +          (*f)->flags&= ~(NOT_NULL_FLAG);
> +          (*f)->null_ptr= nptr;
> +        }
> +        cnt++;
> +    } 
> +    bzero(nptr, (table->s->fields - table->s->null_fields + 7)/8);

what are you doing here?

>      table->triggers->reset_extra_null_bitmap();
>    }
>  }
> diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
> index 4ecd8139921..7de2fde0e5c 100644
> --- a/sql/sql_trigger.cc
> +++ b/sql/sql_trigger.cc
> @@ -1118,7 +1118,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table)
>  
>          f->flags= (*fld)->flags;
>          f->null_ptr= null_ptr;
> -        f->null_bit= null_bit;
> +        f->null_bit= (*fld)->null_bit;
>          if (null_bit == 128)
>            null_ptr++, null_bit= 1;
>          else
> diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
> index f451dfda1ee..c1174bfd36e 100644
> --- a/sql/sql_trigger.h
> +++ b/sql/sql_trigger.h
> @@ -226,6 +226,10 @@ class Table_triggers_list: public Sql_alloc
>                       trigger_table->s->null_fields + 7)/8;
>      bzero(extra_null_bitmap, null_bytes);
>    }
> +  uchar *get_extra_null_bitmap() const
> +  {
> +    return extra_null_bitmap;
> +  }

This is not used anywhere

>  private:
>    bool prepare_record_accessors(TABLE *table);
> 
Regards,
Sergei
VP of MariaDB Server Engineering
and security@xxxxxxxxxxx