Merge of fix for Bug#51070.
This commit is contained in:
commit
06b70326ce
@ -78,6 +78,92 @@ CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
|||||||
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
|
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
|
||||||
DROP VIEW v1, v2;
|
DROP VIEW v1, v2;
|
||||||
#
|
#
|
||||||
|
# Bug#51070: Query with a NOT IN subquery predicate returns a wrong
|
||||||
|
# result set
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( a INT, b INT );
|
||||||
|
INSERT INTO t1 VALUES ( 1, NULL ), ( 2, NULL );
|
||||||
|
CREATE TABLE t2 ( c INT, d INT );
|
||||||
|
INSERT INTO t2 VALUES ( NULL, 3 ), ( NULL, 4 );
|
||||||
|
CREATE TABLE t3 ( e INT, f INT );
|
||||||
|
INSERT INTO t3 VALUES ( NULL, NULL ), ( NULL, NULL );
|
||||||
|
CREATE TABLE t4 ( a INT );
|
||||||
|
INSERT INTO t4 VALUES (1), (2), (3);
|
||||||
|
CREATE TABLE t5 ( a INT );
|
||||||
|
INSERT INTO t5 VALUES (NULL), (2);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
x PRIMARY x x x x x x x x
|
||||||
|
x DEPENDENT SUBQUERY x x x x x x x x
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
a b
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
|
||||||
|
a b
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) IS NULL;
|
||||||
|
a b
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS UNKNOWN;
|
||||||
|
a b
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
SELECT * FROM t1 WHERE (( a, b ) NOT IN ( SELECT c, d FROM t2 )) IS UNKNOWN;
|
||||||
|
a b
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
SELECT * FROM t1 WHERE 1 = 1 AND ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
a b
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
x PRIMARY x x x x x x x x
|
||||||
|
x DEPENDENT SUBQUERY x x x x x x x x
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
a b
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
x PRIMARY x x x x x x x x
|
||||||
|
x DEPENDENT SUBQUERY x x x x x x x x
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
|
||||||
|
c d
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
x PRIMARY x x x x x x x x
|
||||||
|
x DEPENDENT SUBQUERY x x x x x x x x
|
||||||
|
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
e f
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
x PRIMARY x x x x x x x x
|
||||||
|
x DEPENDENT SUBQUERY x x x x x x x x
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
c d
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN
|
||||||
|
( SELECT c, d FROM t2 WHERE c = 1 AND c <> 1 );
|
||||||
|
a b
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
SELECT * FROM t1 WHERE b NOT IN ( SELECT c FROM t2 WHERE c = 1 );
|
||||||
|
a b
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
SELECT * FROM t1 WHERE NULL NOT IN ( SELECT c FROM t2 WHERE c = 1 AND c <> 1 );
|
||||||
|
a b
|
||||||
|
1 NULL
|
||||||
|
2 NULL
|
||||||
|
DROP TABLE t1, t2, t3, t4, t5;
|
||||||
|
#
|
||||||
# End of 5.1 tests.
|
# End of 5.1 tests.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -74,6 +74,68 @@ CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
|||||||
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
|
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
|
||||||
DROP VIEW v1, v2;
|
DROP VIEW v1, v2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#51070: Query with a NOT IN subquery predicate returns a wrong
|
||||||
|
--echo # result set
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 ( a INT, b INT );
|
||||||
|
INSERT INTO t1 VALUES ( 1, NULL ), ( 2, NULL );
|
||||||
|
|
||||||
|
CREATE TABLE t2 ( c INT, d INT );
|
||||||
|
INSERT INTO t2 VALUES ( NULL, 3 ), ( NULL, 4 );
|
||||||
|
|
||||||
|
CREATE TABLE t3 ( e INT, f INT );
|
||||||
|
INSERT INTO t3 VALUES ( NULL, NULL ), ( NULL, NULL );
|
||||||
|
|
||||||
|
CREATE TABLE t4 ( a INT );
|
||||||
|
INSERT INTO t4 VALUES (1), (2), (3);
|
||||||
|
|
||||||
|
CREATE TABLE t5 ( a INT );
|
||||||
|
INSERT INTO t5 VALUES (NULL), (2);
|
||||||
|
|
||||||
|
--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) IS NULL;
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS UNKNOWN;
|
||||||
|
SELECT * FROM t1 WHERE (( a, b ) NOT IN ( SELECT c, d FROM t2 )) IS UNKNOWN;
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE 1 = 1 AND ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
|
||||||
|
--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
|
||||||
|
--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
|
||||||
|
|
||||||
|
--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
|
||||||
|
|
||||||
|
--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||||
|
EXPLAIN
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN
|
||||||
|
( SELECT c, d FROM t2 WHERE c = 1 AND c <> 1 );
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE b NOT IN ( SELECT c FROM t2 WHERE c = 1 );
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE NULL NOT IN ( SELECT c FROM t2 WHERE c = 1 AND c <> 1 );
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3, t4, t5;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 5.1 tests.
|
--echo # End of 5.1 tests.
|
||||||
|
@ -1763,6 +1763,76 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
The implementation of optimized \<outer expression\> [NOT] IN \<subquery\>
|
||||||
|
predicates. The implementation works as follows.
|
||||||
|
|
||||||
|
For the current value of the outer expression
|
||||||
|
|
||||||
|
- If it contains only NULL values, the original (before rewrite by the
|
||||||
|
Item_in_subselect rewrite methods) inner subquery is non-correlated and
|
||||||
|
was previously executed, there is no need to re-execute it, and the
|
||||||
|
previous return value is returned.
|
||||||
|
|
||||||
|
- If it contains NULL values, check if there is a partial match for the
|
||||||
|
inner query block by evaluating it. For clarity we repeat here the
|
||||||
|
transformation previously performed on the sub-query. The expression
|
||||||
|
|
||||||
|
<tt>
|
||||||
|
( oc_1, ..., oc_n )
|
||||||
|
\<in predicate\>
|
||||||
|
( SELECT ic_1, ..., ic_n
|
||||||
|
FROM \<table\>
|
||||||
|
WHERE \<inner where\>
|
||||||
|
)
|
||||||
|
</tt>
|
||||||
|
|
||||||
|
was transformed into
|
||||||
|
|
||||||
|
<tt>
|
||||||
|
( oc_1, ..., oc_n )
|
||||||
|
\<in predicate\>
|
||||||
|
( SELECT ic_1, ..., ic_n
|
||||||
|
FROM \<table\>
|
||||||
|
WHERE \<inner where\> AND ... ( ic_k = oc_k OR ic_k IS NULL )
|
||||||
|
HAVING ... NOT ic_k IS NULL
|
||||||
|
)
|
||||||
|
</tt>
|
||||||
|
|
||||||
|
The evaluation will now proceed according to special rules set up
|
||||||
|
elsewhere. These rules include:
|
||||||
|
|
||||||
|
- The HAVING NOT \<inner column\> IS NULL conditions added by the
|
||||||
|
aforementioned rewrite methods will detect whether they evaluated (and
|
||||||
|
rejected) a NULL value and if so, will cause the subquery to evaluate
|
||||||
|
to NULL.
|
||||||
|
|
||||||
|
- The added WHERE and HAVING conditions are present only for those inner
|
||||||
|
columns that correspond to outer column that are not NULL at the moment.
|
||||||
|
|
||||||
|
- If there is an eligible index for executing the subquery, the special
|
||||||
|
access method "Full scan on NULL key" is employed which ensures that
|
||||||
|
the inner query will detect if there are NULL values resulting from the
|
||||||
|
inner query. This access method will quietly resort to table scan if it
|
||||||
|
needs to find NULL values as well.
|
||||||
|
|
||||||
|
- Under these conditions, the sub-query need only be evaluated in order to
|
||||||
|
find out whether it produced any rows.
|
||||||
|
|
||||||
|
- If it did, we know that there was a partial match since there are
|
||||||
|
NULL values in the outer row expression.
|
||||||
|
|
||||||
|
- If it did not, the result is FALSE or UNKNOWN. If at least one of the
|
||||||
|
HAVING sub-predicates rejected a NULL value corresponding to an outer
|
||||||
|
non-NULL, and hence the inner query block returns UNKNOWN upon
|
||||||
|
evaluation, there was a partial match and the result is UNKNOWN.
|
||||||
|
|
||||||
|
- If it contains no NULL values, the call is forwarded to the inner query
|
||||||
|
block.
|
||||||
|
|
||||||
|
@see Item_in_subselect::val_bool()
|
||||||
|
@see Item_is_not_null_test::val_int()
|
||||||
|
*/
|
||||||
longlong Item_in_optimizer::val_int()
|
longlong Item_in_optimizer::val_int()
|
||||||
{
|
{
|
||||||
bool tmp;
|
bool tmp;
|
||||||
@ -1816,7 +1886,7 @@ longlong Item_in_optimizer::val_int()
|
|||||||
all_left_cols_null= false;
|
all_left_cols_null= false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((Item_in_subselect*)args[1])->is_correlated &&
|
if (!item_subs->is_correlated &&
|
||||||
all_left_cols_null && result_for_null_param != UNKNOWN)
|
all_left_cols_null && result_for_null_param != UNKNOWN)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1830,8 +1900,11 @@ longlong Item_in_optimizer::val_int()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The subquery has to be evaluated */
|
/* The subquery has to be evaluated */
|
||||||
(void) args[1]->val_bool_result();
|
(void) item_subs->val_bool_result();
|
||||||
null_value= !item_subs->engine->no_rows();
|
if (item_subs->engine->no_rows())
|
||||||
|
null_value= item_subs->null_value;
|
||||||
|
else
|
||||||
|
null_value= TRUE;
|
||||||
if (all_left_cols_null)
|
if (all_left_cols_null)
|
||||||
result_for_null_param= null_value;
|
result_for_null_param= null_value;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ Item_subselect::Item_subselect():
|
|||||||
item value is NULL if select_subselect not changed this value
|
item value is NULL if select_subselect not changed this value
|
||||||
(i.e. some rows will be found returned)
|
(i.e. some rows will be found returned)
|
||||||
*/
|
*/
|
||||||
null_value= 1;
|
null_value= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -435,9 +435,9 @@ void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
|
|||||||
|
|
||||||
void Item_singlerow_subselect::reset()
|
void Item_singlerow_subselect::reset()
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= TRUE;
|
||||||
if (value)
|
if (value)
|
||||||
value->null_value= 1;
|
value->null_value= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -582,7 +582,7 @@ double Item_singlerow_subselect::val_real()
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
if (!exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= FALSE;
|
||||||
return value->val_real();
|
return value->val_real();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -597,7 +597,7 @@ longlong Item_singlerow_subselect::val_int()
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
if (!exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= FALSE;
|
||||||
return value->val_int();
|
return value->val_int();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -611,7 +611,7 @@ String *Item_singlerow_subselect::val_str(String *str)
|
|||||||
{
|
{
|
||||||
if (!exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= FALSE;
|
||||||
return value->val_str(str);
|
return value->val_str(str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -626,7 +626,7 @@ my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
|
|||||||
{
|
{
|
||||||
if (!exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= FALSE;
|
||||||
return value->val_decimal(decimal_value);
|
return value->val_decimal(decimal_value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -641,7 +641,7 @@ bool Item_singlerow_subselect::val_bool()
|
|||||||
{
|
{
|
||||||
if (!exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= FALSE;
|
||||||
return value->val_bool();
|
return value->val_bool();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -659,7 +659,7 @@ Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
|
|||||||
bool val_bool();
|
bool val_bool();
|
||||||
init(select_lex, new select_exists_subselect(this));
|
init(select_lex, new select_exists_subselect(this));
|
||||||
max_columns= UINT_MAX;
|
max_columns= UINT_MAX;
|
||||||
null_value= 0; //can't be NULL
|
null_value= FALSE; //can't be NULL
|
||||||
maybe_null= 0; //can't be NULL
|
maybe_null= 0; //can't be NULL
|
||||||
value= 0;
|
value= 0;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -822,15 +822,14 @@ double Item_in_subselect::val_real()
|
|||||||
*/
|
*/
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
null_value= 0;
|
null_value= was_null= FALSE;
|
||||||
if (exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
null_value= 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (was_null && !value)
|
if (was_null && !value)
|
||||||
null_value= 1;
|
null_value= TRUE;
|
||||||
return (double) value;
|
return (double) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,15 +842,14 @@ longlong Item_in_subselect::val_int()
|
|||||||
*/
|
*/
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
null_value= 0;
|
null_value= was_null= FALSE;
|
||||||
if (exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
null_value= 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (was_null && !value)
|
if (was_null && !value)
|
||||||
null_value= 1;
|
null_value= TRUE;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,16 +862,15 @@ String *Item_in_subselect::val_str(String *str)
|
|||||||
*/
|
*/
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
null_value= 0;
|
null_value= was_null= FALSE;
|
||||||
if (exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
null_value= 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (was_null && !value)
|
if (was_null && !value)
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= TRUE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
str->set((ulonglong)value, &my_charset_bin);
|
str->set((ulonglong)value, &my_charset_bin);
|
||||||
@ -884,20 +881,14 @@ String *Item_in_subselect::val_str(String *str)
|
|||||||
bool Item_in_subselect::val_bool()
|
bool Item_in_subselect::val_bool()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
null_value= 0;
|
null_value= was_null= FALSE;
|
||||||
if (exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
/*
|
|
||||||
Must mark the IN predicate as NULL so as to make sure an enclosing NOT
|
|
||||||
predicate will return FALSE. See the comments in
|
|
||||||
subselect_uniquesubquery_engine::copy_ref_key for further details.
|
|
||||||
*/
|
|
||||||
null_value= 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (was_null && !value)
|
if (was_null && !value)
|
||||||
null_value= 1;
|
null_value= TRUE;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,16 +899,15 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
|
|||||||
method should not be used
|
method should not be used
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
null_value= 0;
|
null_value= was_null= FALSE;
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
if (exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
null_value= 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (was_null && !value)
|
if (was_null && !value)
|
||||||
null_value= 1;
|
null_value= TRUE;
|
||||||
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
|
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
|
||||||
return decimal_value;
|
return decimal_value;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user