summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2020-06-16 01:29:51 +0300
committerSergei Petrunia <psergey@askmonty.org>2020-06-16 01:29:51 +0300
commit57b224a5c2b774411ca8f107b3675dd2f340ccee (patch)
tree4a1a3800036712b2a70f0ab6892ca42c9903ce6b /sql/sql_select.cc
parent32b34cb95edc1032381225b58780fc92cb449200 (diff)
downloadmariadb-git-bb-10.3-mdev22866.tar.gz
MDEV-22866: Server crashes in ... with not_null_range_scan=onbb-10.3-mdev22866
Starting from 10.3, the optimizer is able to detect that entire outer join nests are constants (because of "Impossible ON") and remove them (see mark_join_nest_as_const) However, this was not properly accounted for in NESTED_JOIN structure and the way check_interleaving_with_nj() uses its n_tables member to check if the join prefix order is allowed. (The result was that the optimizer could conclude that no join prefix is allowed and fail an assertion)
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc18
1 files changed, 13 insertions, 5 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 05da4a1e750..3d618643d7e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -15823,10 +15823,15 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
/**
- Set NESTED_JOIN::counter=0 in all nested joins in passed list.
+ Set NESTED_JOIN::counter and n_tables in all nested joins in passed list.
- Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
- the passed join_list.
+ For all nested joins contained in the passed join_list (including its
+ children), set:
+ - nested_join->counter=0
+ - nested_join->n_tables= {number of non-degenerate direct children}.
+
+ Non-degenerate means non-const base table or a join nest that has a
+ non-degenerate child.
@param join_list List of nested joins to process. It may also contain base
tables which will be ignored.
@@ -15849,8 +15854,11 @@ static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
if (!nested_join->n_tables)
is_eliminated_nest= TRUE;
}
- if ((table->nested_join && !is_eliminated_nest) ||
- (!table->nested_join && (table->table->map & ~join->eliminated_tables)))
+ const table_map removed_tables= join->eliminated_tables |
+ join->const_table_map;
+
+ if ((table->nested_join && !is_eliminated_nest) ||
+ (!table->nested_join && (table->table->map & ~removed_tables)))
n++;
}
DBUG_RETURN(n);