Skip to content
Permalink
Browse files
Merge branch '10.4' into bb-10.4-release
  • Loading branch information
sanja-byelkin committed Nov 7, 2022
2 parents 0946c99 + 625fff0 commit e9dc395
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 109 deletions.
@@ -1,4 +1,4 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=4
MYSQL_VERSION_PATCH=27
MYSQL_VERSION_PATCH=28
SERVER_MATURITY=stable
@@ -314,6 +314,15 @@ ERROR 23000: Duplicate entry '1' for key 'v2'
update t1,t2 set v1 = v2 , v5 = 0;
ERROR 23000: Duplicate entry '-128' for key 'v1'
drop table t1, t2;
CREATE TABLE t1 (f TEXT UNIQUE);
INSERT INTO t1 VALUES (NULL),(NULL);
UPDATE t1 SET f = '';
ERROR 23000: Duplicate entry '' for key 'f'
SELECT * FROM t1;
f

NULL
DROP TABLE t1;
#
# MDEV-21540 Initialization of already inited long unique index on reorganize partition
#
@@ -396,6 +396,17 @@ update t1 set v2 = 1, v3 = -128;
update t1,t2 set v1 = v2 , v5 = 0;
drop table t1, t2;

#
# MDEV-23264 Unique blobs allow duplicate values upon UPDATE
#

CREATE TABLE t1 (f TEXT UNIQUE);
INSERT INTO t1 VALUES (NULL),(NULL);
--error ER_DUP_ENTRY
UPDATE t1 SET f = '';
SELECT * FROM t1;
DROP TABLE t1;

--echo #
--echo # MDEV-21540 Initialization of already inited long unique index on reorganize partition
--echo #
@@ -469,6 +469,51 @@ a
1
2
3
#
# MDEV-29655: ASAN heap-use-after-free in
# Pushdown_derived::Pushdown_derived
#
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
DEFAULT CHARSET=latin1;
INSERT INTO federated.t1 VALUES
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
connection master;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
use federated;
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=2) dt2) dt;
id name
connection slave;
CREATE TABLE federated.t10 (a INT,b INT);
CREATE TABLE federated.t11 (a INT, b INT);
INSERT INTO federated.t10 VALUES (1,1),(2,2);
INSERT INTO federated.t11 VALUES (1,1),(2,2);
connection master;
CREATE TABLE federated.t10
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t10';
CREATE TABLE federated.t11
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t11';
use federated;
SELECT * FROM t10 LEFT JOIN
(t11, (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=2) dt2) dt
) ON t10.a=t11.a;
a b a b id name
1 1 NULL NULL NULL NULL
2 2 NULL NULL NULL NULL
set global federated_pushdown=0;
connection master;
DROP TABLE IF EXISTS federated.t1;
@@ -267,7 +267,6 @@ INSERT INTO federated.t2
SELECT * FROM (SELECT * FROM federated.t1 LIMIT 70000) dt;
SELECT COUNT(DISTINCT a) FROM federated.t2;


--echo #
--echo # MDEV-29640 FederatedX does not properly handle pushdown
--echo # in case of difference in local and remote table names
@@ -314,6 +313,64 @@ CREATE TABLE federated.t3 (a INT)
EXPLAIN SELECT * FROM federated.t3;
SELECT * FROM federated.t3;

--echo #
--echo # MDEV-29655: ASAN heap-use-after-free in
--echo # Pushdown_derived::Pushdown_derived
--echo #

connection slave;
DROP TABLE IF EXISTS federated.t1;

CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
DEFAULT CHARSET=latin1;

INSERT INTO federated.t1 VALUES
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');

connection master;
DROP TABLE IF EXISTS federated.t1;

--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';

use federated;
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=2) dt2) dt;

connection slave;
CREATE TABLE federated.t10 (a INT,b INT);
CREATE TABLE federated.t11 (a INT, b INT);
INSERT INTO federated.t10 VALUES (1,1),(2,2);
INSERT INTO federated.t11 VALUES (1,1),(2,2);

connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
CREATE TABLE federated.t10
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t10';

--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
CREATE TABLE federated.t11
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t11';

use federated;
SELECT * FROM t10 LEFT JOIN
(t11, (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=2) dt2) dt
) ON t10.a=t11.a;

set global federated_pushdown=0;

source include/federated_cleanup.inc;
@@ -44,11 +44,6 @@ Pushdown_derived::Pushdown_derived(TABLE_LIST *tbl, derived_handler *h)
}


Pushdown_derived::~Pushdown_derived()
{
delete handler;
}


int Pushdown_derived::execute()
{
@@ -1552,12 +1552,6 @@ class Field: public Value_source
Used by the ALTER TABLE
*/
virtual bool is_equal(const Column_definition &new_field) const= 0;
// Used as double dispatch pattern: calls virtual method of handler
virtual bool
can_be_converted_by_engine(const Column_definition &new_type) const
{
return false;
}
/* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
int *err);
@@ -3621,10 +3615,6 @@ class Field_string :public Field_longstr {
void sql_type(String &str) const;
void sql_rpl_type(String*) const;
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_string(this, new_type);
}
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length);
virtual const uchar *unpack(uchar* to, const uchar *from,
@@ -3751,10 +3741,6 @@ class Field_varstring :public Field_longstr {
uchar *new_ptr, uint32 length,
uchar *new_null_ptr, uint new_null_bit);
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_varstring(this, new_type);
}
void hash(ulong *nr, ulong *nr2);
uint length_size() const { return length_bytes; }
void print_key_value(String *out, uint32 length);
@@ -4128,10 +4114,6 @@ class Field_blob :public Field_longstr {
uint32 char_length() const;
uint32 character_octet_length() const;
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_blob(this, new_type);
}
void print_key_value(String *out, uint32 length);

friend void TABLE::remember_blob_values(String *blob_storage);
@@ -4247,10 +4229,6 @@ class Field_geom :public Field_blob {
!table->copy_blobs;
}
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_geom(this, new_type);
}

int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
@@ -1,6 +1,6 @@
/*
Copyright (c) 2005, 2019, Oracle and/or its affiliates.
Copyright (c) 2009, 2021, MariaDB
Copyright (c) 2009, 2022, MariaDB

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -12021,35 +12021,12 @@ void ha_partition::clear_top_table_fields()
}

bool
ha_partition::can_convert_string(const Field_string* field,
const Column_definition& new_type) const
ha_partition::can_convert_nocopy(const Field &field,
const Column_definition &new_type) const
{
for (uint index= 0; index < m_tot_parts; index++)
{
if (!m_file[index]->can_convert_string(field, new_type))
return false;
}
return true;
}

bool
ha_partition::can_convert_varstring(const Field_varstring* field,
const Column_definition& new_type) const{
for (uint index= 0; index < m_tot_parts; index++)
{
if (!m_file[index]->can_convert_varstring(field, new_type))
return false;
}
return true;
}

bool
ha_partition::can_convert_blob(const Field_blob* field,
const Column_definition& new_type) const
{
for (uint index= 0; index < m_tot_parts; index++)
{
if (!m_file[index]->can_convert_blob(field, new_type))
if (!m_file[index]->can_convert_nocopy(field, new_type))
return false;
}
return true;
@@ -1624,16 +1624,8 @@ class ha_partition :public handler

friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
bool can_convert_string(
const Field_string* field,
const Column_definition& new_field) const override;

bool can_convert_varstring(
const Field_varstring* field,
const Column_definition& new_field) const override;

bool can_convert_blob(
const Field_blob* field,
const Column_definition& new_field) const override;
bool can_convert_nocopy(const Field &field,
const Column_definition &new_field) const override;
};
#endif /* HA_PARTITION_INCLUDED */
@@ -6750,8 +6750,13 @@ static int check_duplicate_long_entries_update(TABLE *table, handler *h, uchar *
for (uint j= 0; j < key_parts; j++, keypart++)
{
field= keypart->field;
/* Compare fields if they are different then check for duplicates*/
if(field->cmp_binary_offset(reclength))
/*
Compare fields if they are different then check for duplicates
cmp_binary_offset cannot differentiate between null and empty string
So also check for that too
*/
if((field->is_null(0) != field->is_null(reclength)) ||
field->cmp_binary_offset(reclength))
{
if((error= check_duplicate_long_entry_key(table, table->update_handler,
new_rec, i)))
@@ -4851,23 +4851,8 @@ class handler :public Sql_alloc
These functions check for such possibility.
Implementation could be based on Field_xxx::is_equal()
*/
virtual bool can_convert_string(const Field_string *field,
const Column_definition &new_type) const
{
return false;
}
virtual bool can_convert_varstring(const Field_varstring *field,
const Column_definition &new_type) const
{
return false;
}
virtual bool can_convert_blob(const Field_blob *field,
const Column_definition &new_type) const
{
return false;
}
virtual bool can_convert_geom(const Field_geom *field,
const Column_definition &new_type) const
virtual bool can_convert_nocopy(const Field &,
const Column_definition &) const
{
return false;
}
@@ -1000,11 +1000,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
/* Create an object for execution of the query specifying the table */
if (!(derived->pushdown_derived=
new (thd->mem_root) Pushdown_derived(derived, derived->dt_handler)))
{
delete derived->dt_handler;
derived->dt_handler= NULL;
DBUG_RETURN(TRUE);
}
}

lex->current_select= first_select;
@@ -1229,7 +1225,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
/* Execute the query that specifies the derived table by a foreign engine */
res= derived->pushdown_derived->execute();
unit->executed= true;
delete derived->pushdown_derived;
DBUG_RETURN(res);
}

0 comments on commit e9dc395

Please sign in to comment.