[MDEV-23864] BULK insert wrong values when command contain inner select Created: 2020-10-01  Updated: 2024-01-12

Status: Open
Project: MariaDB Server
Component/s: None
Affects Version/s: 10.4.14, 10.5.5, 10.2, 10.3
Fix Version/s: 10.4, 10.5

Type: Bug Priority: Critical
Reporter: Diego Dupin Assignee: Oleksandr Byelkin
Resolution: Unresolved Votes: 3
Labels: CONNECTOR_RELATED

Issue Links:
Problem/Incident
causes CONJ-1106 executeBatch() uses same sequence for... Closed
causes CONJ-1149 addBatch doesn't cleanup subquery par... Closed

 Description   

When executing an bulk insert with a SELECT as part of the query, the SELECT part will not be treated for every series of parameters.

example to reproduce:

#include <mysql.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char **argv)
{
  printf("MySQL client version: %s\n", mysql_get_client_info());
  MYSQL *con = mysql_init(NULL);
 
  if (con == NULL) {
      fprintf(stderr, "%s\n", mysql_error(con));
      exit(1);
  }
 
  if (mysql_real_connect(con, "localhost", "root", "", NULL, 0, NULL, 0) == NULL) {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }
 
  if (mysql_query(con, "CREATE DATABASE IF NOT EXISTS testdb")) {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }
  printf("Database created\n");
 
 
  if (mysql_query(con, "CREATE TEMPORARY TABLE testdb.my_table(id int, val int)")) {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }
  printf("Table created\n");
 
 
  MYSQL_STMT *stmt;
  stmt = mysql_stmt_init(con);
  if (mysql_stmt_prepare(stmt, "INSERT INTO testdb.my_table(id,val) VALUES( ?, (SELECT ?))", -1) != 0) {
      fprintf(stderr, "Error: %s\n", mysql_stmt_error(stmt));
      return 1;
  }
 
  MYSQL_BIND bind[2];
  int id[3];
  id[0] = 1;
  id[1] = 2;
  id[2] = 3;
 
  int val[3];
  val[0] = 10;
  val[1] = 20;
  val[2] = 30;
 
  char id_ind = STMT_INDICATOR_NONE;
  char val_ind = STMT_INDICATOR_NONE;
 
  memset(bind, 0, sizeof(bind));
  bind[0].u.indicator = &id_ind;
  bind[0].buffer_type = MYSQL_TYPE_LONG;
  bind[0].buffer = &id;
  bind[1].u.indicator = &val_ind;
  bind[1].buffer_type = MYSQL_TYPE_LONG;
  bind[1].buffer = &val;
 
  if (mysql_stmt_bind_param(stmt, bind) != 0) {
      fprintf(stderr, "Error: %s\n", mysql_stmt_error(stmt));
      return 1;
  }
 
  unsigned int numrows = 3;
  mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &numrows);
  if (mysql_stmt_execute(stmt) != 0) {
      fprintf(stderr, "Error: %s\n", mysql_stmt_error(stmt));
      mysql_close(con);
      exit(1);
  }
  printf("Results:\n");
 
  if (mysql_query(con, "SELECT * FROM testdb.my_table")) {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }
 
  MYSQL_RES *result = mysql_store_result(con);
  if (result == NULL) {
      printf("No data !?");
      mysql_close(con);
      exit(1);
  }
 
  int num_fields = mysql_num_fields(result);
  MYSQL_ROW row;
  while ((row = mysql_fetch_row(result))) {
      for (int i = 0; i < num_fields; i++) {
          printf("%s ", row[i] ? row[i] : "NULL");
      }
      printf("\n");
  }
  mysql_free_result(result);
 
  mysql_close(con);
  exit(0);
}

This returns
Results:
1 10
2 10
NULL 10

but expected
1 10
2 20
3 30

(the null value but expected 3 must probably be an example error, but I don't see why)


Generated at Thu Feb 08 09:25:38 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.