[MDEV-23778] Derived table handler loses data on conversion from HEAP to Aria Created: 2020-09-21  Updated: 2022-05-06  Resolved: 2020-09-29

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - Federated
Affects Version/s: 10.4, 10.5
Fix Version/s: 10.4.16, 10.5.7

Type: Bug Priority: Blocker
Reporter: Alexander Barkov Assignee: Igor Babaev
Resolution: Fixed Votes: 0
Labels: derived

Issue Links:
Relates
relates to MCOL-4222 Import from Table fails or writing em... Closed

 Description   

Derived table handler returns wrong results when a temporary HEAP table gets full and converts to an Aria table. After conversion, the Aria table have DEFAULT values for all fields rather than real values from the derived table query.

This test demonstrates the problems:

--source have_federatedx.inc
--source include/federated.inc
 
connection default;
 
set global federated_pushdown=1;
 
connection slave;
 
CREATE TABLE federated.t1 (
  a varchar(100) NOT NULL default '123'
)
DEFAULT CHARSET=latin1;
 
CREATE TABLE federated.t2 LIKE federated.t1;
 
DELIMITER $$;
BEGIN NOT ATOMIC
  DECLARE i INT DEFAULT 0;
  START TRANSACTION;
  WHILE i < 70000 DO
    INSERT INTO federated.t1 VALUES (i);
    SET i = i + 1;
  END WHILE;
  COMMIT;
END
$$
 
DELIMITER ;$$
 
connection master;
 
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
CREATE TABLE federated.t1 (
  a varchar(100) NOT NULL default '123'
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
 
 
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
CREATE TABLE federated.t2 (
  a varchar(100) NOT NULL default '123'
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2';
 
--echo #
--echo # This correctly returns 70000
--echo #
 
SELECT COUNT(DISTINCT a) FROM federated.t1;
 
--echo #
--echo # This correctly returns 100
--echo #
 
INSERT INTO federated.t2 SELECT * FROM (SELECT * FROM federated.t1 LIMIT 100) derived;
SELECT COUNT(DISTINCT a) FROM federated.t2;
 
--echo #
--echo # This erroneously returns 1
--echo #
 
TRUNCATE TABLE federated.t2;
INSERT INTO federated.t2 SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) derived;
SELECT COUNT(DISTINCT a) FROM federated.t2;
 
 
--echo #
--echo # This correctly returns 70000  
--echo #
 
SET global federated_pushdown=0;
TRUNCATE TABLE federated.t2;
INSERT INTO federated.t2 SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) derived;
SELECT COUNT(DISTINCT a) FROM federated.t2;
 
source include/federated_cleanup.inc;

The problem happens because create_internal_tmp_table_from_heap() is called with "start_recinfo" and "recinfo" pointing to some non-initialized memory (instead of the real table structure), so create_internal_tmp_table_from_heap() thinks the table has no data columns. Thus, instead of copying from HEAP Fields to Aria Fields, it puts records consisting of default values to Aria.

Thread 30 "mariadbd" hit Breakpoint 10, create_internal_tmp_table_from_heap (thd=0x7fff9800d268, table=0x7fff980cac40, 
    start_recinfo=0xa5a5a5a5a5a5a5a5, recinfo=0x7fff980e95b0, error=135, ignore_last_dupp_key_error=true, 
    is_duplicate=0x7fffdcaed83f) at /home/bar/maria-git/server.10.5.cs2/sql/sql_select.cc:19794
19794	  TABLE new_table;

The wrong table structure information seems to come from here:

void derived_handler::set_derived(TABLE_LIST *tbl)
{
  derived= tbl;
  table= tbl->table;
  unit= tbl->derived;
  select= unit->first_select();
  tmp_table_param= select->next_select() ?
                   ((select_unit *)(unit->result))->get_tmp_table_param() :
                   &select->join->tmp_table_param;
}

tmp_table_param gets assigned to &select->join->tmp_table_param, which is not properly initialized, it seems.



 Comments   
Comment by Igor Babaev [ 2020-09-29 ]

A fix for this bug was pushed into 10.4.

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