GithubHelp home page GithubHelp logo

Comments (5)

midenok avatar midenok commented on September 26, 2024

1. derived->merged_for_insert flag is set

#0  mysql_derived_merge_for_insert (thd=0x7fff74000cf8, lex=0x7fff74004b50, derived=0x7fff74012fd8) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:524
#1  0x00000000007acdf4 in mysql_handle_single_derived (lex=0x7fff74004b50, derived=0x7fff74012fd8, phases=16) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:206
#2  0x000000000096aebf in TABLE_LIST::handle_derived (this=0x7fff74012fd8, lex=0x7fff74004b50, phases=16) at /home/midenok/src/mariadb/trunk/src/sql/table.cc:8666
#3  0x000000000093835e in mysql_update (thd=0x7fff74000cf8, table_list=0x7fff74012fd8, select_lex=0x7fff740053f8, values=..., limit=18446744073709551615, ignore=false, found_return=0x7ffff461ce88, updated_return=0x7ffff461ce80) at /home/midenok/src/mariadb/trunk/src/sql/sql_update.cc:420
#4  0x000000000080ecec in mysql_execute_command (thd=0x7fff74000cf8) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:4634
#5  0x0000000000805d00 in mysql_parse (thd=0x7fff74000cf8, rawbuf=0x7fff74012f00 "update v1 set x= 2", length=18, parser_state=0x7ffff461e640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:8157

It assigns derived->table:

    if (derived->merge_underlying_list)
    {
      derived->table= derived->merge_underlying_list->table;
      derived->schema_table= derived->merge_underlying_list->schema_table;
      derived->merged_for_insert= TRUE;
      DBUG_ASSERT(derived->table);
    }

2. mysql_derived_prepare()

#0  mysql_derived_prepare (thd=0x7fff74000cf8, lex=0x7fff74004b50, derived=0x7fff74012fd8) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:658
#1  0x00000000007acdf4 in mysql_handle_single_derived (lex=0x7fff74004b50, derived=0x7fff74012fd8, phases=2) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:206
#2  0x000000000096aebf in TABLE_LIST::handle_derived (this=0x7fff74012fd8, lex=0x7fff74004b50, phases=2) at /home/midenok/src/mariadb/trunk/src/sql/table.cc:8666
#3  0x00000000009383b7 in mysql_update (thd=0x7fff74000cf8, table_list=0x7fff74012fd8, select_lex=0x7fff740053f8, values=..., limit=18446744073709551615, ignore=false, found_return=0x7ffff461ce88, updated_return=0x7ffff461ce80) at /home/midenok/src/mariadb/trunk/src/sql/sql_update.cc:422
#4  0x000000000080ecec in mysql_execute_command (thd=0x7fff74000cf8) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:4634
#5  0x0000000000805d00 in mysql_parse (thd=0x7fff74000cf8, rawbuf=0x7fff74012f00 "update v1 set x= 2", length=18, parser_state=0x7ffff461e640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:8157

This could be without merged_for_insert flag:

#0  st_select_lex::vers_setup_conds (this=0x7fff84015608, thd=0x7fff84000cf8, tables=0x7fff84015c30) at /home/midenok/src/mariadb/trunk/src/sql/sql_select.cc:946
#1  0x0000000000859d52 in JOIN::prepare (this=0x7fff84017188, tables_init=0x7fff84015c30, wild_num=0, conds_init=0x0, og_num=0, order_init=0x0, skip_order_by=false, group_init=0x0, having_init=0x0, proc_param_init=0x0, select_lex_arg=0x7fff84015608, unit_arg=0x7fff84013b90) at /home/midenok/src/mariadb/trunk/src/sql/sql_select.cc:1183
#2  0x0000000000934143 in st_select_lex_unit::prepare_join (this=0x7fff84013b90, thd_arg=0x7fff84000cf8, sl=0x7fff84015608, tmp_result=0x7fff840170a0, additional_options=0, is_union_select=false) at /home/midenok/src/mariadb/trunk/src/sql/sql_union.cc:655
#3  0x000000000092eec8 in st_select_lex_unit::prepare (this=0x7fff84013b90, derived_arg=0x7fff84012fd8, sel_result=0x7fff840170a0, additional_options=0) at /home/midenok/src/mariadb/trunk/src/sql/sql_union.cc:979
#4  0x00000000007a967c in mysql_derived_prepare (thd=0x7fff84000cf8, lex=0x7fff84004b50, derived=0x7fff84012fd8) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:784
#5  0x00000000007accb4 in mysql_handle_single_derived (lex=0x7fff84004b50, derived=0x7fff84012fd8, phases=2) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:206
#6  0x000000000096ad7f in TABLE_LIST::handle_derived (this=0x7fff84012fd8, lex=0x7fff84004b50, phases=2) at /home/midenok/src/mariadb/trunk/src/sql/table.cc:8666
#7  0x0000000000938277 in mysql_update (thd=0x7fff84000cf8, table_list=0x7fff84012fd8, select_lex=0x7fff840053f8, values=..., limit=18446744073709551615, ignore=false, found_return=0x7ffff461ce88, updated_return=0x7ffff461ce80) at /home/midenok/src/mariadb/trunk/src/sql/sql_update.cc:422
#8  0x000000000080ebac in mysql_execute_command (thd=0x7fff84000cf8) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:4634
#9  0x0000000000805bc0 in mysql_parse (thd=0x7fff84000cf8, rawbuf=0x7fff84012f00 "update v1 set x= 2", length=18, parser_state=0x7ffff461e640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:8157

3. vers_setup_conds()

#0  st_select_lex::vers_setup_conds (this=0x7fff740053f8, thd=0x7fff74000cf8, tables=0x7fff74012fd8) at /home/midenok/src/mariadb/trunk/src/sql/sql_select.cc:946
#1  0x000000000093c347 in mysql_prepare_update (thd=0x7fff74000cf8, table_list=0x7fff74012fd8, conds=0x7ffff461b328, order_num=0, order=0x0) at /home/midenok/src/mariadb/trunk/src/sql/sql_update.cc:1376
#2  0x0000000000938566 in mysql_update (thd=0x7fff74000cf8, table_list=0x7fff74012fd8, select_lex=0x7fff740053f8, values=..., limit=18446744073709551615, ignore=false, found_return=0x7ffff461ce88, updated_return=0x7ffff461ce80) at /home/midenok/src/mariadb/trunk/src/sql/sql_update.cc:445
#3  0x000000000080ecec in mysql_execute_command (thd=0x7fff74000cf8) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:4634
#4  0x0000000000805d00 in mysql_parse (thd=0x7fff74000cf8, rawbuf=0x7fff74012f00 "update v1 set x= 2", length=18, parser_state=0x7ffff461e640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:8157

from mariadb.

midenok avatar midenok commented on September 26, 2024

Good: got conds from derived subquery

#0  TABLE_LIST::prep_where (this=0x7fff84012f38, thd=0x7fff84000cf8, conds=0x7ffff464d340, no_where_clause=false) at /home/midenok/src/mariadb/10.4/src/sql/table.cc:5374
#1  0x0000000000768940 in TABLE_LIST::prepare_where (this=0x7fff84012f38, thd=0x7fff84000cf8, conds=0x7ffff464d340, no_where_clause=false) at /home/midenok/src/mariadb/10.4/src/sql/table.h:2520
#2  0x0000000000761c69 in setup_conds (thd=0x7fff84000cf8, tables=0x7fff84012f38, leaves=..., conds=0x7ffff464d340) at /home/midenok/src/mariadb/10.4/src/sql/sql_base.cc:8313
#3  0x000000000093b0e3 in mysql_prepare_update (thd=0x7fff84000cf8, table_list=0x7fff84012f38, conds=0x7ffff464d340, order_num=0, order=0x0) at /home/midenok/src/mariadb/10.4/src/sql/sql_update.cc:1387
#4  0x00000000009373b7 in mysql_update (thd=0x7fff84000cf8, table_list=0x7fff84012f38, fields=..., values=..., conds=0x7fff84016660, order_num=0, order=0x0, limit=18446744073709551615, ignore=false, found_return=0x7ffff464ee88, updated_return=0x7ffff464ee80) at /home/midenok/src/mariadb/10.4/src/sql/sql_update.cc:442
#5  0x000000000080e290 in mysql_execute_command (thd=0x7fff84000cf8) at /home/midenok/src/mariadb/10.4/src/sql/sql_parse.cc:4634
#6  0x0000000000805270 in mysql_parse (thd=0x7fff84000cf8, rawbuf=0x7fff84012e60 "update vn1 set x= x + 1", length=23, parser_state=0x7ffff4650640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/10.4/src/sql/sql_parse.cc:8157
5368          if (tbl == 0)
5369          {
5370            if (*conds)
5371              res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
5372            if (!res)
5373              *conds= and_conds(thd, *conds, where->copy_andor_structure(thd));
5374            if (*conds && !res)
5375              res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
5376          }

Actually it collects all conds recursively from underlying tables:

5326      for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
5327      {
5328        if (tbl->is_view_or_derived() &&
5329            tbl->prep_where(thd, conds, no_where_clause))
5330        {
5331          DBUG_RETURN(TRUE);
5332        }
5333      }

frame 2

And this works only for merged_for_insert:

8319      for (table= tables; table; table= table->next_local)
8320      {
8321        if (select_lex == thd->lex->first_select_lex() &&
8322            select_lex->first_cond_optimization &&
8323            table->merged_for_insert &&
8324            table->prepare_where(thd, conds, FALSE))
8325          goto err_no_arena;
8326      }

from mariadb.

midenok avatar midenok commented on September 26, 2024

Good: view TABLE_LIST::where gets conds from select_lex

#0  mysql_make_view (thd=0x7fff84000cf8, share=0x7fff84089f30, table=0x7fff84012f38, open_view_no_parse=false) at /home/midenok/src/mariadb/10.4/src/sql/sql_view.cc:1698
#1  0x0000000000752761 in open_table (thd=0x7fff84000cf8, table_list=0x7fff84012f38, ot_ctx=0x7ffff464c7a8) at /home/midenok/src/mariadb/10.4/src/sql/sql_base.cc:1963
#2  0x00000000007575a5 in open_and_process_table (thd=0x7fff84000cf8, tables=0x7fff84012f38, counter=0x7ffff464d314, flags=0, prelocking_strategy=0x7ffff464c8b8, has_prelocking_list=false, ot_ctx=0x7ffff464c7a8) at /home/midenok/src/mariadb/10.4/src/sql/sql_base.cc:3802
#3  0x0000000000756132 in open_tables (thd=0x7fff84000cf8, options=..., start=0x7ffff464d358, counter=0x7ffff464d314, sroutine_to_open_list=0x7fff84004be0, flags=0, prelocking_strategy=0x7ffff464c8b8) at /home/midenok/src/mariadb/10.4/src/sql/sql_base.cc:4301
#4  0x0000000000739d13 in open_tables (thd=0x7fff84000cf8, options=..., tables=0x7ffff464d358, counter=0x7ffff464d314, flags=0, prelocking_strategy=0x7ffff464c8b8) at /home/midenok/src/mariadb/10.4/src/sql/sql_base.h:258
#5  0x000000000074a116 in open_tables (thd=0x7fff84000cf8, tables=0x7ffff464d358, counter=0x7ffff464d314, flags=0) at /home/midenok/src/mariadb/10.4/src/sql/sql_base.h:481
#6  0x0000000000936e1b in mysql_update (thd=0x7fff84000cf8, table_list=0x7fff84012f38, fields=..., values=..., conds=0x0, order_num=0, order=0x0, limit=18446744073709551615, ignore=false, found_return=0x7ffff464ee88, updated_return=0x7ffff464ee80) at /home/midenok/src/mariadb/10.4/src/sql/sql_update.cc:387
#7  0x000000000080e290 in mysql_execute_command (thd=0x7fff84000cf8) at /home/midenok/src/mariadb/10.4/src/sql/sql_parse.cc:4634
#8  0x0000000000805270 in mysql_parse (thd=0x7fff84000cf8, rawbuf=0x7fff84012e60 "update vn1 set x= x + 1", length=23, parser_state=0x7ffff4650640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/10.4/src/sql/sql_parse.cc:8157
1685          /* prepare view context */
1686          lex->first_select_lex()->
1687            context.resolve_in_table_list_only(view_main_select_tables);
1688          lex->first_select_lex()->context.outer_context= 0;
1689          lex->first_select_lex()->select_n_having_items+=
1690            table->select_lex->select_n_having_items;
1691
1692          table->where= view_select->where;

from mariadb.

midenok avatar midenok commented on September 26, 2024

Bug 2: assertion on removing "temporary table"

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff733b535 in __GI_abort () at abort.c:79
#2  0x00007ffff733b40f in __assert_fail_base (fmt=0x7ffff74c9588 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x16a45a9 "m_lock_type == 2", file=0x16a2fc8 "/home/midenok/src/mariadb/trunk/src/sql/handler.cc", line=4692, function=<optimized out>) at assert.c:92
#3  0x00007ffff734b012 in __GI___assert_fail (assertion=0x16a45a9 "m_lock_type == 2", file=0x16a2fc8 "/home/midenok/src/mariadb/trunk/src/sql/handler.cc", line=4692, function=0x16a47de "void handler::ha_drop_table(const char *)") at assert.c:101
#4  0x0000000000b87ca3 in handler::ha_drop_table (this=0x7fff8002fc80, name=0x7fff8002c788 "./test/t1") at /home/midenok/src/mariadb/trunk/src/sql/handler.cc:4692
#5  0x000000000087eb42 in free_tmp_table (thd=0x7fff80000cf8, entry=0x7fff8002ee88) at /home/midenok/src/mariadb/trunk/src/sql/sql_select.cc:19406
#6  0x000000000075040f in close_thread_tables (thd=0x7fff80000cf8) at /home/midenok/src/mariadb/trunk/src/sql/sql_base.cc:900
#7  0x0000000000815953 in mysql_execute_command (thd=0x7fff80000cf8) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:6413
#8  0x0000000000805d30 in mysql_parse (thd=0x7fff80000cf8, rawbuf=0x7fff80012f00 "update v1 set x= x + 1", length=22, parser_state=0x7ffff461e640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:8157

frame 6

890       if (thd->derived_tables)
891       {
892         TABLE *next;
893         /*
894           Close all derived tables generated in queries like
895           SELECT * FROM (SELECT * FROM t1)
896         */
897         for (table= thd->derived_tables ; table ; table= next)
898         {
899           next= table->next;
900           free_tmp_table(thd, table);
901         }

Good

thd->derived_tables is never set

Bad: thd->derived_tables set

#0  mysql_derived_prepare (thd=0x7fff80000cf8, lex=0x7fff80004b50, derived=0x7fff80012fd8) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:904
#1  0x00000000007ace24 in mysql_handle_single_derived (lex=0x7fff80004b50, derived=0x7fff80012fd8, phases=2) at /home/midenok/src/mariadb/trunk/src/sql/sql_derived.cc:206
#2  0x000000000096b12f in TABLE_LIST::handle_derived (this=0x7fff80012fd8, lex=0x7fff80004b50, phases=2) at /home/midenok/src/mariadb/trunk/src/sql/table.cc:8666
#3  0x0000000000938627 in mysql_update (thd=0x7fff80000cf8, table_list=0x7fff80012fd8, select_lex=0x7fff800053f8, values=..., limit=18446744073709551615, ignore=false, found_return=0x7ffff461ce88, updated_return=0x7ffff461ce80) at /home/midenok/src/mariadb/trunk/src/sql/sql_update.cc:422
#4  0x000000000080ed1c in mysql_execute_command (thd=0x7fff80000cf8) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:4634
#5  0x0000000000805d30 in mysql_parse (thd=0x7fff80000cf8, rawbuf=0x7fff80012f00 "update v1 set x= x + 1", length=22, parser_state=0x7ffff461e640, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/trunk/src/sql/sql_parse.cc:8157
897         if (!derived->is_with_table_recursive_reference())
898         {
899           table->next= thd->derived_tables;
900           thd->derived_tables= table;
901         }

Cause

--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -720,6 +720,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
   // Skip already prepared views/DT
   if (unit->prepared ||
       (derived->merged_for_insert && 
+       !derived->table->versioned() &&
        !(derived->is_multitable() &&
          (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
           thd->lex->sql_command == SQLCOM_DELETE_MULTI))))

This condition is just to call st_select_lex_unit::prepare() later:

785       if ((res= unit->prepare(derived, derived->derived_result, 0)))
786         goto exit;

from mariadb.

midenok avatar midenok commented on September 26, 2024

Fix

VIEW update was broken by endless loop because versioning conditions didn't apply.
VIEW itself is not a versioned table (it has no row_start, row_end), but rather a derived table which is processed by mysql_derived_prepare(). And it was not called because of merged_for_insert flag (see above). So the solution is to make additional call when this flag is set, because anything else is not needed.

Another problem is that after vers_setup_conds() it didn't get versioning conditions into conds for mysql_update() (see TABLE_LIST::prep_where()).

diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 06e82263524..06a3e8a108f 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -723,7 +723,17 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
        !(derived->is_multitable() &&
          (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
           thd->lex->sql_command == SQLCOM_DELETE_MULTI))))
+  {
+    /*
+       System versioned tables may still require to get versioning conditions
+       (when updating view). See vers_setup_conds().
+    */
+    if (!unit->prepared &&
+        derived->table->versioned() &&
+        (res= unit->prepare(derived, derived->derived_result, 0)))
+      goto exit;
     DBUG_RETURN(FALSE);
+  }
 
   /* prevent name resolving out of derived table */
   for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7c609acdb1b..c69fa233a5b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1086,7 +1086,16 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
     if (is_select)
       table->on_expr= and_items(thd, table->on_expr, cond);
     else
-      where= and_items(thd, where, cond);
+    {
+      if (join)
+      {
+        where= and_items(thd, join->conds, cond);
+        join->conds= where;
+      }
+      else
+        where= and_items(thd, where, cond);
+      table->where= and_items(thd, table->where, cond);
+    }
 
     table->vers_conditions.type= SYSTEM_TIME_ALL;
   } // for (table= tables; ...)
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 41f4234c13d..3f33f1c4d29 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -976,9 +976,21 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
       if (sl->tvc->prepare(thd, sl, tmp_result, this))
 	goto err;
     }
-    else if (prepare_join(thd, first_sl, tmp_result, additional_options,
+    else
+    {
+      if (prepare_join(thd, first_sl, tmp_result, additional_options,
                      is_union_select))
-      goto err;
+        goto err;
+
+      if (derived_arg && derived_arg->table &&
+          derived_arg->derived_type == VIEW_ALGORITHM_MERGE &&
+          derived_arg->table->versioned())
+      {
+        /* Got versioning conditions (see vers_setup_conds()), need to update
+           derived_arg. */
+        derived_arg->where= first_sl->where;
+      }
+    }
     types= first_sl->item_list;
     goto cont;
   }

from mariadb.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.