[MDEV-15133] array bound (bulk) parameters of NULL propagate on next rows Created: 2018-01-30  Updated: 2020-08-25  Due: 2018-01-31  Resolved: 2018-02-12

Status: Closed
Project: MariaDB Server
Component/s: Prepared Statements
Affects Version/s: 10.3.4
Fix Version/s: 10.2.13, 10.3.5

Type: Bug Priority: Critical
Reporter: Michael Widenius Assignee: Oleksandr Byelkin
Resolution: Fixed Votes: 1
Labels: None


 Description   

When using BULK insert of arrays, if there is a NULL in the data for a column, all following rows will also have NULL for the same column.



 Comments   
Comment by Oleksandr Byelkin [ 2018-01-30 ]

static int bulk_null_null(MYSQL *mysql)
{
  struct st_bulk4 {
    char char_value[20];
    char indicator1;
    int  int_value;
    char indicator2;
  };
 
  struct st_bulk4 val[]= {{"Row 1", STMT_INDICATOR_NTS, 3, STMT_INDICATOR_NONE},
                          {"Row 2", STMT_INDICATOR_NULL, 3, STMT_INDICATOR_NULL},
                          {"Row 3", STMT_INDICATOR_NTS, 3, STMT_INDICATOR_NONE}};
  int rc;
  MYSQL_BIND bind[2];
  MYSQL_RES *res;
  MYSQL_STMT *stmt= mysql_stmt_init(mysql);
  size_t row_size= sizeof(struct st_bulk4);
  int array_size= 3;
  unsigned long lengths[3]= {-1, -1, -1};
 
  if (!bulk_enabled)
    return SKIP;
  rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_null");
  check_mysql_rc(rc,mysql);
  rc= mysql_query(mysql, "CREATE TABLE bulk_null (name varchar(20), row int)");
  check_mysql_rc(rc,mysql);
 
  rc= mysql_stmt_prepare(stmt, "INSERT INTO bulk_null VALUES (?,?)", -1);
  check_stmt_rc(rc, stmt);
 
  memset(bind, 0, sizeof(MYSQL_BIND)*2);
  
  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
  check_stmt_rc(rc, stmt);
  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
  check_stmt_rc(rc, stmt);
 
  bind[0].buffer_type= MYSQL_TYPE_STRING;
  bind[0].u.indicator= &val[0].indicator1;
  bind[0].buffer= &val[0].char_value;
  bind[0].length= lengths;
  bind[1].buffer_type= MYSQL_TYPE_LONG;
  bind[1].buffer= &val[0].int_value;
  bind[1].u.indicator= &val[0].indicator2;
 
  rc= mysql_stmt_bind_param(stmt, bind);
  check_stmt_rc(rc, stmt);
  rc= mysql_stmt_execute(stmt);
  check_stmt_rc(rc, stmt);
 
  mysql_stmt_close(stmt);
 
  rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE row=3");
  check_mysql_rc(rc, mysql);
  res= mysql_store_result(mysql);
  rc= (int)mysql_num_rows(res);
  mysql_free_result(res);
  FAIL_IF(rc != 2, "expected 2 rows");
  rc= mysql_query(mysql, "DROP TABLE bulk_null");
  check_mysql_rc(rc, mysql);
  return OK;
}

Comment by Oleksandr Byelkin [ 2018-01-30 ]

Problem is that Item_param::null_value is not reset by set_(int_decimal...) methods after it was set_null.

10.2 has exactly the same problem, but it masked by Item_param::save_in_field() which do not process null_value (work only according to Item_param::state).

Generated at Thu Feb 08 08:18:56 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.