Commit 9a02fede authored by unknown's avatar unknown
Browse files

Fixed bug #18279: crash in the cases when on conditions are moved

out of a nested join to the on conditions for the nest.
The bug happened due to:
1. The function simplify_joins could change on expressions for nested joins.
   Yet modified on expressions were not saved in prep_on_expr.
2. On expressions were not restored for nested joins in 
   reinit_stmt_before_use.


mysql-test/r/join_nested.result:
  Added a test case for bug #18279.
mysql-test/t/join_nested.test:
  Added a test case for bug #18279.
sql/sql_prepare.cc:
  Fixed bug #18279.
  On expressions were not restored for nested joins in 
  reinit_stmt_before_use.
sql/sql_select.cc:
  Fixed bug #18279.
  The function simplify_joins could change on expressions for nested joins.
  Yet modified on expressions were not saved in prep_on_expr.
parent c5ab0159
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -1504,3 +1504,61 @@ id type cid id pid pid type
1	A	NULL	NULL	NULL	NULL	NULL
DROP VIEW v1;
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t2 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t3 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t4 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t5 (id1 int PRIMARY KEY, id2 int);
SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
LEFT OUTER JOIN
(t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
ON t3.id2 IS NOT NULL
WHERE t1.id1=2;
id	ngroupbynsa
PREPARE stmt FROM
"SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
  FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
       LEFT OUTER JOIN
       (t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
       ON t3.id2 IS NOT NULL
    WHERE t1.id1=2";
EXECUTE stmt;
id	ngroupbynsa
EXECUTE stmt;
id	ngroupbynsa
EXECUTE stmt;
id	ngroupbynsa
EXECUTE stmt;
id	ngroupbynsa
INSERT INTO t1 VALUES (1,1), (2,1), (3,2);
INSERT INTO t2 VALUES (2,1), (3,2), (4,3);
INSERT INTO t3 VALUES (1,1), (3,2), (2,NULL);
INSERT INTO t4 VALUES (1,1), (2,1), (3,3);
INSERT INTO t5 VALUES (1,1), (2,2), (3,3), (4,3);
EXECUTE stmt;
id	ngroupbynsa
2	1
2	1
EXECUTE stmt;
id	ngroupbynsa
2	1
2	1
EXECUTE stmt;
id	ngroupbynsa
2	1
2	1
EXECUTE stmt;
id	ngroupbynsa
2	1
2	1
SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
LEFT OUTER JOIN
(t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
ON t3.id2 IS NOT NULL
WHERE t1.id1=2;
id	ngroupbynsa
2	1
2	1
DROP TABLE t1,t2,t3,t4,t5;
+52 −0
Original line number Diff line number Diff line
@@ -942,3 +942,55 @@ SELECT * FROM t1 p LEFT JOIN v1 ON p.id=v1.id

DROP VIEW v1;
DROP TABLE t1,t2,t3;


#
# Test for bug #18279: crash when on conditions are moved out of a nested join
#                      to the on conditions for the nest

CREATE TABLE t1 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t2 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t3 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t4 (id1 int PRIMARY KEY, id2 int);
CREATE TABLE t5 (id1 int PRIMARY KEY, id2 int);

SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
  FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
       LEFT OUTER JOIN
       (t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
       ON t3.id2 IS NOT NULL
    WHERE t1.id1=2;

PREPARE stmt FROM
"SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
  FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
       LEFT OUTER JOIN
       (t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
       ON t3.id2 IS NOT NULL
    WHERE t1.id1=2";

EXECUTE stmt; 
EXECUTE stmt; 
EXECUTE stmt; 
EXECUTE stmt;

INSERT INTO t1 VALUES (1,1), (2,1), (3,2);
INSERT INTO t2 VALUES (2,1), (3,2), (4,3);
INSERT INTO t3 VALUES (1,1), (3,2), (2,NULL);
INSERT INTO t4 VALUES (1,1), (2,1), (3,3);
INSERT INTO t5 VALUES (1,1), (2,2), (3,3), (4,3);

EXECUTE stmt; 
EXECUTE stmt; 
EXECUTE stmt; 
EXECUTE stmt;

SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
  FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1
       LEFT OUTER JOIN
       (t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1)
       ON t3.id2 IS NOT NULL
    WHERE t1.id1=2; 

DROP TABLE t1,t2,t3,t4,t5;
+9 −3
Original line number Diff line number Diff line
@@ -2126,11 +2126,17 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
    /* Reset is_schema_table_processed value(needed for I_S tables */
    tables->is_schema_table_processed= FALSE;

    if (tables->prep_on_expr)
    TABLE_LIST *embedded; /* The table at the current level of nesting. */
    TABLE_LIST *embedding= tables; /* The parent nested table reference. */
    do
    {
      tables->on_expr= tables->prep_on_expr->copy_andor_structure(thd);
      tables->on_expr->cleanup();
      embedded= embedding;
      if (embedded->prep_on_expr)
        embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
      embedding= embedded->embedding;
    }
    while (embedding &&
           embedding->nested_join->join_list.head() == embedded);
  }
  lex->current_select= &lex->select_lex;

+4 −2
Original line number Diff line number Diff line
@@ -7469,7 +7469,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
      */
      if (table->on_expr)
      {
        Item *expr= table->prep_on_expr ? table->prep_on_expr : table->on_expr;
        Item *expr= table->on_expr;
        /* 
           If an on expression E is attached to the table, 
           check all null rejected predicates in this expression.
@@ -7480,7 +7480,9 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
	*/ 
        expr= simplify_joins(join, &nested_join->join_list,
                             expr, FALSE);
        table->prep_on_expr= table->on_expr= expr;
        table->on_expr= expr;
        if (!table->prep_on_expr)
          table->prep_on_expr= expr->copy_andor_structure(join->thd);
      }
      nested_join->used_tables= (table_map) 0;
      nested_join->not_null_tables=(table_map) 0;