summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2022-06-23 06:29:57 +0200
committerVladislav Vaintroub <wlad@mariadb.com>2022-06-23 06:29:57 +0200
commiteb7f46ca1e7a8dc90b587b38c0f2b64a975c73a3 (patch)
tree3e4473a55865ee965bce0bf991983dbf14d19469
parent0f0a45b2dc9fe3c54ca9d146db8068b50fc97138 (diff)
parent35f2cdcb99f4f8b39895070fde3f825329106361 (diff)
downloadmariadb-git-eb7f46ca1e7a8dc90b587b38c0f2b64a975c73a3.tar.gz
Merge remote-tracking branch 'origin/10.5' into 10.6
-rw-r--r--mysql-test/main/range.result19
-rw-r--r--mysql-test/main/range.test18
-rw-r--r--mysql-test/main/range_mrr_icp.result19
-rw-r--r--sql/sql_select.cc14
-rw-r--r--tpool/tpool_generic.cc17
5 files changed, 73 insertions, 14 deletions
diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result
index aca500bf038..81098118abd 100644
--- a/mysql-test/main/range.result
+++ b/mysql-test/main/range.result
@@ -3635,6 +3635,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
a pk b
DROP TABLE t1, t2;
SET @@optimizer_switch= @save_optimizer_switch;
+
+# MDEV-28858 Wrong result with table elimination combined with
+# not_null_range_scan
+#
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,1),(null,2);
+CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(2);
+SET @save_optimizer_switch= @@optimizer_switch;
+SET optimizer_switch= 'not_null_range_scan=on';
+SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
+b
+2
+SET optimizer_switch= 'not_null_range_scan=off';
+SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
+b
+2
+SET @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2;
#
# End of 10.5 tests
#
diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test
index 6a2e318e732..a785726cb22 100644
--- a/mysql-test/main/range.test
+++ b/mysql-test/main/range.test
@@ -2492,6 +2492,24 @@ DROP TABLE t1, t2;
SET @@optimizer_switch= @save_optimizer_switch;
+--echo
+--echo # MDEV-28858 Wrong result with table elimination combined with
+--echo # not_null_range_scan
+--echo #
+
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,1),(null,2);
+CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(2);
+
+SET @save_optimizer_switch= @@optimizer_switch;
+SET optimizer_switch= 'not_null_range_scan=on';
+SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
+SET optimizer_switch= 'not_null_range_scan=off';
+SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
+SET @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2;
+
--echo #
--echo # End of 10.5 tests
--echo #
diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result
index eb4daf7fbc8..e68af8545cf 100644
--- a/mysql-test/main/range_mrr_icp.result
+++ b/mysql-test/main/range_mrr_icp.result
@@ -3624,6 +3624,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
a pk b
DROP TABLE t1, t2;
SET @@optimizer_switch= @save_optimizer_switch;
+
+# MDEV-28858 Wrong result with table elimination combined with
+# not_null_range_scan
+#
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,1),(null,2);
+CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(2);
+SET @save_optimizer_switch= @@optimizer_switch;
+SET optimizer_switch= 'not_null_range_scan=on';
+SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
+b
+2
+SET optimizer_switch= 'not_null_range_scan=off';
+SELECT t1.b FROM t1 LEFT JOIN t2 ON t1.a = t2.pk WHERE t1.a IS NULL ORDER BY t1.b;
+b
+2
+SET @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2;
#
# End of 10.5 tests
#
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c71911f12cd..447ec9c2f73 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -29976,11 +29976,12 @@ bool build_notnull_conds_for_range_scans(JOIN *join, Item *cond,
DBUG_ENTER("build_notnull_conds_for_range_scans");
- for (JOIN_TAB *s= join->join_tab + join->const_tables ;
+ for (JOIN_TAB *s= join->join_tab;
s < join->join_tab + join->table_count ; s++)
{
/* Clear all needed bitmaps to mark found fields */
- if (allowed & s->table->map)
+ if ((allowed & s->table->map) &&
+ !(s->table->map && join->const_table_map))
bitmap_clear_all(&s->table->tmp_set);
}
@@ -29995,17 +29996,18 @@ bool build_notnull_conds_for_range_scans(JOIN *join, Item *cond,
For each table t from 'allowed' build a conjunction of NOT NULL predicates
constructed for all found fields if they are included in some indexes.
If the construction of the conjunction succeeds attach the formula to
- t->table->notnull_cond. The condition will be used to look for complementary
- range scans.
+ t->table->notnull_cond. The condition will be used to look for
+ complementary range scans.
*/
- for (JOIN_TAB *s= join->join_tab + join->const_tables ;
+ for (JOIN_TAB *s= join->join_tab ;
s < join->join_tab + join->table_count ; s++)
{
TABLE *tab= s->table;
List<Item> notnull_list;
Item *notnull_cond= 0;
- if (!(allowed & tab->map))
+ if (!(allowed & tab->map) ||
+ (s->table->map && join->const_table_map))
continue;
for (Field** field_ptr= tab->field; *field_ptr; field_ptr++)
diff --git a/tpool/tpool_generic.cc b/tpool/tpool_generic.cc
index dfd780e7ea3..5d99783e8b9 100644
--- a/tpool/tpool_generic.cc
+++ b/tpool/tpool_generic.cc
@@ -327,21 +327,22 @@ public:
int m_period;
std::mutex m_mtx;
bool m_on;
- std::atomic<bool> m_running;
+ std::atomic<int> m_running;
void run()
{
/*
In rare cases, multiple callbacks can be scheduled,
- e.g with set_time(0,0) in a loop.
- We do not allow parallel execution, as user is not prepared.
+ at the same time,. e.g with set_time(0,0) in a loop.
+ We do not allow parallel execution, since it is against the expectations.
*/
- bool expected = false;
- if (!m_running.compare_exchange_strong(expected, true))
+ if (m_running.fetch_add(1, std::memory_order_acquire) > 0)
return;
-
- m_callback(m_data);
- m_running = false;
+ do
+ {
+ m_callback(m_data);
+ }
+ while (m_running.fetch_sub(1, std::memory_order_release) != 1);
if (m_pool && m_period)
{