Skip to content

Commit 5b84c86

Browse files
committed
Bug#24834622 - ASSERT IN UPDATING VIEW METADATA FOR SYS SCHEMA VIEW.
While updating view columns metadata, assert condition is hit for the datetime type column with default value as bitmap TABLE::read_set is not set. TABLE has a bitmap read_set. A bit in this bitmap is set for a field of a table used in the query. But this bitmap is not set (for outer-most query block) while resolving derived tables. A flag THD::derived_tables_processing is used to indicate the derived table processing. DDL operation on a table, views or stored function(sf) updates a view columns metadata if there are any views referencing them. The view columns metadata is updated as below, * List all the views using table, views or sf used in the DDL operation and even other views dependent on view(s) already included in the list. * For all views in the list, ** Prepare query expression for a view query with the new definition of table/view/sf. ** Update view columns metadata using the query expression prepared for a view query. (In error scenarios mark view as invalid and continue with next view in list.) While preparing query expression for a view, if the derived table processing fails in a situation like missing other table, view or sf (while preparing the query expression of the derived table) then the flag THD::derived_tables_processing is not reset in the current code. This affects processing next view in the list and we end-up not setting read_set flags in TABLE. Hence assert condition to check bitmaps THD::read_set while accessing fields (of type datatime in this scenario) fails. Modified code to reset THD::derived_tables_processing flag in in all error handling code path while resolving derived tables to fix this issue.
1 parent 6aa6ad4 commit 5b84c86

File tree

3 files changed

+122
-13
lines changed

3 files changed

+122
-13
lines changed

mysql-test/r/dd_view_columns.result

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,39 @@ DROP TABLES t1,t3;
600600
DROP FUNCTION sf1;
601601
DEALLOCATE PREPARE check_view_columns;
602602
DEALLOCATE PREPARE check_view_status;
603+
#
604+
# Bug#24834622 - ASSERT IN UPDATING VIEW METADATA FOR SYS SCHEMA VIEW.
605+
#
606+
# Creating views with dependency on view/base table/stored functions
607+
# as below,
608+
# View v2 is dependent on stored function f2.
609+
# View v1 is dependent on stored function f1 and view v2.
610+
# View z1 is dependent on view v2 and table t1 (having datetime column).
611+
CREATE TABLE t1 (f1 DATETIME default '2016-11-01');
612+
CREATE FUNCTION f1() RETURNS INT return 1;
613+
CREATE FUNCTION f2() RETURNS INT return 2;
614+
CREATE VIEW v2 AS SELECT f2() AS f2;
615+
CREATE VIEW v1 AS SELECT v2.f2 AS f2,
616+
a3.x as f3 from v2,
617+
(SELECT a.x FROM (SELECT f1() AS x)
618+
as a HAVING a.x=1) as a3;
619+
CREATE VIEW z1 AS SELECT t1.f1 AS f1, v2.f2 AS f2 FROM t1, v2;
620+
# View v1 is dependent on stored function f1 and view v2.
621+
# Dropping stored function f1 leaves view v1 in invalid state.
622+
DROP FUNCTION f1;
623+
# View v2 is dependent on stored function f2.
624+
# Dropping stored function f2 leaves view v2 and views using v2
625+
# (i.e v1 and z1) in invalid state.
626+
DROP FUNCTION f2;
627+
# Recreating the stored function f2 updates columns of dependent view v2
628+
# and views dependent on v2 (i.e. v1 and z1) in DD tables COLUMNS.
629+
# View v1 is dependent on f1 too. So parsing view v1 fails while
630+
# updating views column metadata.
631+
# Without fix, THD::derived_tables_processing is not unset to false
632+
# on view v1 parse failure. This causes an assert condition failure while
633+
# updating metadata of datatime type column of view z1 as read flag
634+
# for column is not set with the THD::derived_tables_processing on.
635+
CREATE FUNCTION f2() RETURNS INT return 2;
636+
DROP FUNCTION f2;
637+
DROP VIEW v1, v2, z1;
638+
DROP TABLE t1;

mysql-test/t/dd_view_columns.test

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,50 @@ DROP TABLES t1,t3;
466466
DROP FUNCTION sf1;
467467
DEALLOCATE PREPARE check_view_columns;
468468
DEALLOCATE PREPARE check_view_status;
469+
470+
471+
--echo #
472+
--echo # Bug#24834622 - ASSERT IN UPDATING VIEW METADATA FOR SYS SCHEMA VIEW.
473+
--echo #
474+
475+
--echo # Creating views with dependency on view/base table/stored functions
476+
--echo # as below,
477+
--echo # View v2 is dependent on stored function f2.
478+
--echo # View v1 is dependent on stored function f1 and view v2.
479+
--echo # View z1 is dependent on view v2 and table t1 (having datetime column).
480+
481+
CREATE TABLE t1 (f1 DATETIME default '2016-11-01');
482+
483+
CREATE FUNCTION f1() RETURNS INT return 1;
484+
CREATE FUNCTION f2() RETURNS INT return 2;
485+
486+
CREATE VIEW v2 AS SELECT f2() AS f2;
487+
CREATE VIEW v1 AS SELECT v2.f2 AS f2,
488+
a3.x as f3 from v2,
489+
(SELECT a.x FROM (SELECT f1() AS x)
490+
as a HAVING a.x=1) as a3;
491+
CREATE VIEW z1 AS SELECT t1.f1 AS f1, v2.f2 AS f2 FROM t1, v2;
492+
493+
--echo # View v1 is dependent on stored function f1 and view v2.
494+
--echo # Dropping stored function f1 leaves view v1 in invalid state.
495+
DROP FUNCTION f1;
496+
497+
--echo # View v2 is dependent on stored function f2.
498+
--echo # Dropping stored function f2 leaves view v2 and views using v2
499+
--echo # (i.e v1 and z1) in invalid state.
500+
DROP FUNCTION f2;
501+
502+
--echo # Recreating the stored function f2 updates columns of dependent view v2
503+
--echo # and views dependent on v2 (i.e. v1 and z1) in DD tables COLUMNS.
504+
--echo # View v1 is dependent on f1 too. So parsing view v1 fails while
505+
--echo # updating views column metadata.
506+
--echo # Without fix, THD::derived_tables_processing is not unset to false
507+
--echo # on view v1 parse failure. This causes an assert condition failure while
508+
--echo # updating metadata of datatime type column of view z1 as read flag
509+
--echo # for column is not set with the THD::derived_tables_processing on.
510+
CREATE FUNCTION f2() RETURNS INT return 2;
511+
512+
# Cleanup
513+
DROP FUNCTION f2;
514+
DROP VIEW v1, v2, z1;
515+
DROP TABLE t1;

sql/sql_derived.cc

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,51 @@ bool TABLE_LIST::resolve_derived(THD *thd, bool apply_semijoin)
257257
{
258258
DBUG_ENTER("TABLE_LIST::resolve_derived");
259259

260+
/*
261+
Helper class which takes care of restoration of THD::LEX::allow_sum_func
262+
and THD::derived_tables_processing. These members are changed in this
263+
method scope for resolving derived tables.
264+
*/
265+
class Context_handler
266+
{
267+
public:
268+
Context_handler(THD *thd)
269+
: m_thd(thd),
270+
m_allow_sum_func_saved(thd->lex->allow_sum_func),
271+
m_derived_tables_processing_saved(thd->derived_tables_processing)
272+
{
273+
/*
274+
Since derived tables do not allow outer references, they cannot allow
275+
aggregation to occur in any outer query blocks.
276+
*/
277+
m_thd->lex->allow_sum_func= 0;
278+
279+
m_thd->derived_tables_processing= true;
280+
}
281+
282+
~Context_handler()
283+
{
284+
m_thd->lex->allow_sum_func= m_allow_sum_func_saved;
285+
m_thd->derived_tables_processing= m_derived_tables_processing_saved;
286+
}
287+
private:
288+
// Thread handle.
289+
THD *m_thd;
290+
291+
// Saved state of THD::LEX::allow_sum_func.
292+
nesting_map m_allow_sum_func_saved;
293+
294+
// Saved state of THD::derived_tables_processing.
295+
bool m_derived_tables_processing_saved;
296+
};
297+
260298
if (!is_view_or_derived() || is_merged())
261299
DBUG_RETURN(false);
262300

263301
// Dummy derived tables for recursive references disappear before this stage
264302
DBUG_ASSERT(this != select_lex->recursive_reference);
265303

266-
const bool derived_tables_saved= thd->derived_tables_processing;
267-
thd->derived_tables_processing= true;
304+
Context_handler ctx_handler(thd);
268305

269306
if (derived->prepare_limit(thd, derived->global_parameters()))
270307
DBUG_RETURN(true); /* purecov: inspected */
@@ -386,13 +423,6 @@ bool TABLE_LIST::resolve_derived(THD *thd, bool apply_semijoin)
386423
if (!(derived_result= new (thd->mem_root) Query_result_union(thd)))
387424
DBUG_RETURN(true); /* purecov: inspected */
388425

389-
/*
390-
Since derived tables do not allow outer references, they cannot allow
391-
aggregation to occur in any outer query blocks.
392-
*/
393-
nesting_map allow_sum_func_saved= thd->lex->allow_sum_func;
394-
thd->lex->allow_sum_func= 0;
395-
396426
/*
397427
Prepare the underlying query expression of the derived table.
398428
The SELECT_STRAIGHT_JOIN option prevents semi-join transformation.
@@ -419,10 +449,6 @@ bool TABLE_LIST::resolve_derived(THD *thd, bool apply_semijoin)
419449
set_privileges(SELECT_ACL);
420450
}
421451

422-
thd->lex->allow_sum_func= allow_sum_func_saved;
423-
424-
thd->derived_tables_processing= derived_tables_saved;
425-
426452
DBUG_RETURN(false);
427453
}
428454

0 commit comments

Comments
 (0)