diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 2a0b62ebaf0..e36932cbc0c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3503,17 +3503,46 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, if (inv) { - /* - We get here for conditions like "t.keypart NOT IN (....)". - - If the IN-list contains only constants (and func->array is an ordered - array of them), we construct the appropriate SEL_ARG tree manually, - because constructing it using the range analyzer (as - AND_i( t.keypart != c_i)) will cause lots of memory to be consumed - (see BUG#15872). - */ if (func->array && func->cmp_type != ROW_RESULT) { + /* + We get here for conditions in form "t.key NOT IN (c1, c2, ...)" + (where c{i} are constants). + Our goal is to produce a SEL_ARG graph that represents intervals: + + ($MINmem_root; + param->thd->mem_root= param->old_root; /* Create one Item_type constant object. We'll need it as get_mm_parts only accepts constant values wrapped in Item_Type @@ -3522,24 +3551,13 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, per-statement mem_root (while thd->mem_root is currently pointing to mem_root local to range optimizer). */ - MEM_ROOT *tmp_root= param->mem_root; - param->thd->mem_root= param->old_root; Item *value_item= func->array->create_item(); param->thd->mem_root= tmp_root; if (!value_item) break; - /* - Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. - Note: for partially-covering keys the returned tree may represent - a half-closed interval (-inf < X <= c_0). In that case the for the - whole NOT IN statement the (-inf < X < +inf) interval will be - constructed. It doesn't make sense to consider range access over - such intervals, but we don't eliminate them here as 1) they are - handled correctly by all parts of the code, and 2) the case where - such intervals are constructed is rare. - */ + /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */ uint i=0; do {