Skip to content

Commit 9676f0d

Browse files
author
Dag Wanvik
committed
Bug#21696206: ASSERTION `TRANSL->ITEM->FIXED' FAILED IN SELECT_LEX::DELETE_UNUSED_MERGED_COLUMN
It turns out that the standalone PREPARE doesn't call apply_local_transforms from mysql_prepare_insert, in contrast to mysql_prepare_delete and mysql_prepare_update. This has the effect that this resolve phase operation isn't performed when a standalone prepared insert is performed. Now, at PS execution time, the code in Sql_cmd_insert::mysql_insert does call apply_local_transforms - for the first time. The fact that it is the first call implies this method's call to fix_prepare_information hasn't been called before. This again means that the value of st_select_lex::first_execution == true when we first enter apply_local_transforms (during EXECUTE). Now, apply_local_transforms tests on this flag in this stanza: if (derived_table_count && first_execution && !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)) delete_unused_merged_columns(&top_join_list); Since first_execution is true, the call to delete_unused_merged_columns is done. This is not supposed to have happened, the unused item is no longer fixed, and the ASSERT happens. Lifting the ASSERT doen't help; we crash later in sql_authorization.cc:2274 instead. Adding the call to apply_local_transforms at the end of mysql_prepare_insert makes the statement work, since we now do the work of apply_local_transforms also at prepare time, as for DELETE and UPDATE. We only do this if mysql_prepare_insert is not called for a INSERT..SELECT since for those statements, apply_local_transforms *are* called during prepare already (from st_select_lex_unit::prepare), and calling it can cause things to break, e.g. one of the tests for WL-5275 in insert.test, cf. discussion on the bug entry. This patch also fixes Bug#21696641, so test cases have been added for both 21696206 and 21696641.
1 parent 7f3978e commit 9676f0d

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

mysql-test/r/insert.result

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,3 +761,45 @@ INSERT INTO v1 VALUES(3);
761761
REPLACE INTO v1 VALUES(3);
762762
DROP VIEW v1;
763763
DROP TABLE t1;
764+
#
765+
# Bug#21696206: ASSERTION `TRANSL->ITEM->FIXED' FAILED IN
766+
# SELECT_LEX::DELETE_UNUSED_MERGED_COLUMN
767+
#
768+
CREATE TABLE t1 ( pk INT, PRIMARY KEY (pk));
769+
CREATE TABLE t2 LIKE t1;
770+
INSERT INTO t1 VALUES (2);
771+
INSERT INTO t2 VALUES (2);
772+
CREATE VIEW v1 AS SELECT * FROM t2 AS a
773+
WHERE a.pk IN ( SELECT pk FROM t1 AS b WHERE b.pk = a.pk );
774+
CREATE VIEW v2 AS SELECT * FROM t1 AS a
775+
WHERE a.pk IN ( SELECT pk FROM v1 AS b WHERE b.pk = a.pk );
776+
PREPARE st1 FROM 'INSERT INTO v2 (pk) VALUES ( 1 )';
777+
EXECUTE st1;
778+
SELECT * FROM t1;
779+
pk
780+
1
781+
2
782+
SELECT * FROM t2;
783+
pk
784+
2
785+
DROP TABLE t1, t2;
786+
DROP VIEW v1, v2;
787+
#
788+
# Bug#21696641: ASSERTION !(WANT_PRIVILEGE & ~(GRANT->WANT_PRIVILEGE |
789+
# GRANT->PRIVILEGE))'
790+
#
791+
CREATE TABLE t1 (pk INT, PRIMARY KEY (pk));
792+
INSERT INTO t1 VALUES (1);
793+
CREATE ALGORITHM = TEMPTABLE VIEW v2 AS
794+
SELECT * FROM t1 AS a NATURAL JOIN t1 b WHERE pk BETWEEN 1 AND 2;
795+
CREATE ALGORITHM = UNDEFINED VIEW v1 AS
796+
SELECT * FROM t1 AS a
797+
WHERE a.pk IN ( SELECT pk FROM v2 AS b WHERE b.pk = a.pk );
798+
PREPARE st1 FROM "INSERT INTO v1 (pk) VALUES (2)";
799+
EXECUTE st1;
800+
SELECT * FROM t1;
801+
pk
802+
1
803+
2
804+
DROP VIEW v1, v2;
805+
DROP TABLE t1;

mysql-test/t/insert.test

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,3 +604,50 @@ REPLACE INTO v1 VALUES(3);
604604

605605
DROP VIEW v1;
606606
DROP TABLE t1;
607+
608+
--echo #
609+
--echo # Bug#21696206: ASSERTION `TRANSL->ITEM->FIXED' FAILED IN
610+
--echo # SELECT_LEX::DELETE_UNUSED_MERGED_COLUMN
611+
--echo #
612+
CREATE TABLE t1 ( pk INT, PRIMARY KEY (pk));
613+
CREATE TABLE t2 LIKE t1;
614+
615+
INSERT INTO t1 VALUES (2);
616+
INSERT INTO t2 VALUES (2);
617+
618+
CREATE VIEW v1 AS SELECT * FROM t2 AS a
619+
WHERE a.pk IN ( SELECT pk FROM t1 AS b WHERE b.pk = a.pk );
620+
621+
CREATE VIEW v2 AS SELECT * FROM t1 AS a
622+
WHERE a.pk IN ( SELECT pk FROM v1 AS b WHERE b.pk = a.pk );
623+
624+
PREPARE st1 FROM 'INSERT INTO v2 (pk) VALUES ( 1 )';
625+
EXECUTE st1;
626+
627+
SELECT * FROM t1;
628+
SELECT * FROM t2;
629+
630+
DROP TABLE t1, t2;
631+
DROP VIEW v1, v2;
632+
633+
--echo #
634+
--echo # Bug#21696641: ASSERTION !(WANT_PRIVILEGE & ~(GRANT->WANT_PRIVILEGE |
635+
--echo # GRANT->PRIVILEGE))'
636+
--echo #
637+
CREATE TABLE t1 (pk INT, PRIMARY KEY (pk));
638+
INSERT INTO t1 VALUES (1);
639+
640+
CREATE ALGORITHM = TEMPTABLE VIEW v2 AS
641+
SELECT * FROM t1 AS a NATURAL JOIN t1 b WHERE pk BETWEEN 1 AND 2;
642+
643+
CREATE ALGORITHM = UNDEFINED VIEW v1 AS
644+
SELECT * FROM t1 AS a
645+
WHERE a.pk IN ( SELECT pk FROM v2 AS b WHERE b.pk = a.pk );
646+
647+
PREPARE st1 FROM "INSERT INTO v1 (pk) VALUES (2)";
648+
EXECUTE st1;
649+
650+
SELECT * FROM t1;
651+
652+
DROP VIEW v1, v2;
653+
DROP TABLE t1;

sql/sql_insert.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,9 @@ bool Sql_cmd_insert_base::mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
14241424
DBUG_RETURN(true);
14251425
}
14261426

1427+
if (!select_insert && select_lex->apply_local_transforms(thd, false))
1428+
DBUG_RETURN(true);
1429+
14271430
DBUG_RETURN(false);
14281431
}
14291432

0 commit comments

Comments
 (0)