tempesta-tech / mariadb

MariaDB System Versioning
GNU General Public License v2.0
6 stars 5 forks source link

Historical identifiers mode (3w) #126

Closed midenok closed 4 years ago

midenok commented 7 years ago

Task scope

Description

3 modes of historical SELECT identifiers switched by global/session variable versioning_identifier_mode:

See Mode 2 of DDL traverse.

There is no difference between HISTORICAL_EARLY and HISTORICAL for AS OF queries. For FROM .. TO, BETWEEN .. AND HISTORICAL_EARLY selects lower timestamp of range, HISTORICAL selects higher timestamp of range.

Depends on #199

kevgs commented 7 years ago
#0  __GI_raise (sig=sig@entry=6) at raise.c:51
#1  __GI_abort () at abort.c:90
#2  __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x533ef2 "!strcmp(table_list->get_db_name(), table_list->mdl_request.key.db_name()) && !strcmp(table_list->get_table_name(), table_list->mdl_request.key.name())", file=file@entry=0x533f89 "/home/kevg/work/mariadb/sql/sql_base.cc", line=line@entry=204, function=function@entry=0x533fb1 "uint get_table_def_key(const TABLE_LIST *, const char **)") at assert.c:92
#3  __GI___assert_fail (assertion=0x533ef2 "!strcmp(table_list->get_db_name(), table_list->mdl_request.key.db_name()) && !strcmp(table_list->get_table_name(), table_list->mdl_request.key.name())", file=0x533f89 "/home/kevg/work/mariadb/sql/sql_base.cc", line=204, function=0x533fb1 "uint get_table_def_key(const TABLE_LIST *, const char **)") at assert.c:101
#4  get_table_def_key (table_list=0x7fff90167a40, key=0x7ffff02f3f50) at sql_base.cc:201
#5  open_table (thd=0x7fff90000d50, table_list=0x7fff90167a40, ot_ctx=0x7ffff02f42d8) at sql_base.cc:1523
#6  open_and_process_table (thd=0x7fff90000d50, lex=0x7fff901686b8, tables=0x7fff90167a40, counter=0x7ffff02f43dc, flags=0, prelocking_strategy=0x7ffff02f4450, has_prelocking_list=false, ot_ctx=0x7ffff02f42d8) at sql_base.cc:3414
#7  open_tables (thd=0x7fff90000d50, options=..., start=0x7ffff02f43f0, counter=0x7ffff02f43dc, flags=0, prelocking_strategy=0x7ffff02f4450) at sql_base.cc:3932
#8  open_and_lock_tables (thd=0x7fff90000d50, options=..., tables=0x7fff90167a40, derived=true, flags=0, prelocking_strategy=0x7ffff02f4450) at sql_base.cc:4687
#9  open_and_lock_tables (thd=0x7fff90000d50, tables=0x7fff90167a40, derived=true, flags=0) at sql_base.h:493
#10 execute_sqlcom_select (thd=0x7fff90000d50, all_tables=0x7fff90167a40) at sql_parse.cc:6392
#11 mysql_execute_command (thd=0x7fff90000d50) at sql_parse.cc:3575
#12 sp_instr_stmt::exec_core (this=0x7fff90168080, thd=0x7fff90000d50, nextp=0x7ffff02f9908) at sp_head.cc:3344
#13 sp_lex_keeper::reset_lex_and_exec_core (this=0x7fff901680c8, thd=0x7fff90000d50, nextp=0x7ffff02f9908, open_tables=false, instr=0x7fff90168080) at sp_head.cc:3088
#14 sp_instr_stmt::execute (this=0x7fff90168080, thd=0x7fff90000d50, nextp=0x7ffff02f9908) at sp_head.cc:3260
#15 sp_head::execute (this=0x7fff90166618, thd=0x7fff90000d50, merge_da_on_success=true) at sp_head.cc:1233
#16 sp_head::execute_procedure (this=0x7fff90166618, thd=0x7fff90000d50, args=0x7fff90005688) at sp_head.cc:2059
#17 do_execute_sp (thd=0x7fff90000d50, sp=0x7fff90166618) at sql_parse.cc:2883
#18 mysql_execute_command (thd=0x7fff90000d50) at sql_parse.cc:5811
#19 mysql_parse (thd=0x7fff90000d50, rawbuf=0x7fff900129a8 "call select_a_from_range()", length=26, parser_state=0x7ffff02ff528, is_com_multi=false, is_next_command=false) at sql_parse.cc:7918

(gdb) p table_list->get_table_name()
$1 = 0x7fff9016eca0 '\245' <repeats 200 times>...
(gdb) p table_list->mdl_request.key.name()
$2 = 0x7fff90167eb6 "t_20171002_164442_689222"
midenok commented 7 years ago

Addition:

For versioning_identifer_mode=current do simple column mapping (without CMMD walk, as it is not yet implemented in #205). I.e. the scope of your task is:

  1. For field F in current table get column ID C_ID (index in TABLE_SHARE::field[]);
  2. Get field F_ARCH in archive table as TABLE_SHARE::field[C_ID].
kevgs commented 7 years ago

Opening a table in a middle a query looks like this:

        TABLE_LIST tl;
        tl.init_one_table(C_STRING_WITH_LEN("test"), C_STRING_WITH_LEN("t"),
                          "t", TL_READ);
        Open_tables_backup open_tables_backup;
        thd->reset_n_backup_open_tables_state(&open_tables_backup);
        bool can_deadlock= thd->mdl_context.has_locks();
        if (!open_tables_only_view_structure(thd, &tl, can_deadlock))
        {
          close_thread_tables(thd);
        }
        thd->mdl_context.rollback_to_savepoint(
            open_tables_backup.mdl_system_tables_svp);
        thd->restore_backup_open_tables_state(&open_tables_backup);
kevgs commented 7 years ago
(gdb) bt
#0  Item_field::set_field (this=0x7fff90012a40, field_par=0x7fff90028838) at item.cc:2750
#1  Item_field::fix_fields (this=0x7fff90012a40, thd=0x7fff90000d50, reference=0x7fff90012b40) at item.cc:5755
#2  setup_fields (thd=0x7fff90000d50, ref_pointer_array=..., fields=List<Item> with 1 elements, mark_used_columns=MARK_COLUMNS_READ, sum_func_list=0x7fff900135c8, allow_sum_func=true) at sql_base.cc:7124
#3  JOIN::prepare (this=0x7fff900132b0, tables_init=0x7fff90012b80, 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=0x7fff900050a0, unit_arg=0x7fff90004940) at sql_select.cc:1168
#4  mysql_select (thd=0x7fff90000d50, tables=0x7fff90012b80, wild_num=0, fields=List<Item> with 1 elements, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147748608, result=0x7fff90013290, unit=0x7fff90004940, select_lex=0x7fff900050a0) at sql_select.cc:4055
#5  handle_select (thd=0x7fff90000d50, lex=0x7fff90004878, result=0x7fff90013290, setup_tables_done_option=0) at sql_select.cc:363
#6  execute_sqlcom_select (thd=0x7fff90000d50, all_tables=0x7fff90012b80) at sql_parse.cc:6561
#7  mysql_execute_command (thd=0x7fff90000d50) at sql_parse.cc:3575
#8  mysql_parse (thd=0x7fff90000d50, rawbuf=0x7fff900129a8 "select a from t", length=15, parser_state=0x7ffff02ff528, is_com_multi=false, is_next_command=false) at sql_parse.cc:8008
#9  dispatch_command (command=COM_QUERY, thd=0x7fff90000d50, packet=0x7fff90008d61 "select a from t", packet_length=15, is_com_multi=false, is_next_command=false) at sql_parse.cc:1814
midenok commented 7 years ago

Unknown column error

#0  my_error (nr=1054, MyFlags=0) at /home/midenok/src/mariadb/midenok/src/mysys/my_error.c:109
#1  0x0000555555aebeec in find_field_in_tables (thd=0x7fff80000d50, item=0x7fff800134d8, first_table=0x7fff80013618, last_table=0x0, ref=0x7fff800135d8, report_error=REPORT_ALL_ERRORS, check_privileges=true, register_tree_change=true) at /home/midenok/src/mariadb/midenok/src/sql/sql_base.cc:6010
#2  0x0000555555e2a490 in Item_field::fix_outer_field (this=0x7fff800134d8, thd=0x7fff80000d50, from_field=0x7fffe54b0c78, reference=0x7fff800135d8) at /home/midenok/src/mariadb/midenok/src/sql/item.cc:5472
#3  0x0000555555e2af55 in Item_field::fix_fields (this=0x7fff800134d8, thd=0x7fff80000d50, reference=0x7fff800135d8) at /home/midenok/src/mariadb/midenok/src/sql/item.cc:5709
#4  0x0000555555aeeaa8 in setup_fields (thd=0x7fff80000d50, ref_pointer_array=..., fields=..., mark_used_columns=MARK_COLUMNS_READ, sum_func_list=0x7fff80014060, allow_sum_func=true) at /home/midenok/src/mariadb/midenok/src/sql/sql_base.cc:7124
#5  0x0000555555ba1f09 in JOIN::prepare (this=0x7fff80013d48, tables_init=0x7fff80013618, 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=0x7fff80005098, unit_arg=0x7fff80004938) at /home/midenok/src/mariadb/midenok/src/sql/sql_select.cc:1168
#6  0x0000555555bac7cf in mysql_select (thd=0x7fff80000d50, tables=0x7fff80013618, wild_num=0, fields=..., conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147748608, result=0x7fff80013d28, unit=0x7fff80004938, select_lex=0x7fff80005098) at /home/midenok/src/mariadb/midenok/src/sql/sql_select.cc:4055
#7  0x0000555555b9ec82 in handle_select (thd=0x7fff80000d50, lex=0x7fff80004870, result=0x7fff80013d28, setup_tables_done_option=0) at /home/midenok/src/mariadb/midenok/src/sql/sql_select.cc:363
#8  0x0000555555b69dde in execute_sqlcom_select (thd=0x7fff80000d50, all_tables=0x7fff80013618) at /home/midenok/src/mariadb/midenok/src/sql/sql_parse.cc:6476
#9  0x0000555555b6195e in mysql_execute_command (thd=0x7fff80000d50) at /home/midenok/src/mariadb/midenok/src/sql/sql_parse.cc:3575
#10 0x0000555555b6d100 in mysql_parse (thd=0x7fff80000d50, rawbuf=0x7fff80013438 "select z from m1", length=16, parser_state=0x7fffe54b26a0, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/midenok/src/sql/sql_parse.cc:7923
midenok commented 7 years ago

Accessing fields in HISTORICAL mode

Substitute TABLE_LIST::table_name in VTMD_table::setup_select().

Accessing fields in CURRENT mode

  1. Add archive table to list of opening tables;
  2. Do name resolution against current table;
  3. Get field->field_index of resolved Item_field, make index mapping -> get field_index of archive table;
  4. Assign Item_field::field with field from 3.

CURRENT mode implementation

  1. Modify VTMD_table::setup_select() for CURRENT mode: a) add archive TABLE_LIST to list of opened tables; b) add achive TABLE_LIST to TABLE_LIST::vers_archive_table of current TABLE_LIST.
  2. Modify Item_field::fix_fields(): for CURRENT mode after from_field is resolved take its field_index and assign from_field with archive table field. Archive table is accessed from TABLE_LIST::vers_archive_table.
kevgs commented 6 years ago

Subtasks: