From 3a64d55aede6db2b3d520e7fbc17e70cfeb8916e Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Fri, 13 Jan 2017 13:56:01 +0000 Subject: [PATCH] Parser, SQL: table-specific FOR SYSTEM_TIME [closes #116] * Syntax sugar: query-global QUERY FOR SYSTEM_TIME --- .../versioning/r/optimized_fields.result | 12 +- mysql-test/suite/versioning/r/select.result | 6 +- mysql-test/suite/versioning/r/view.result | 2 +- .../suite/versioning/t/optimized_fields.test | 12 +- mysql-test/suite/versioning/t/select.test | 6 +- sql/item.cc | 6 +- sql/sql_lex.cc | 15 +++ sql/sql_lex.h | 3 + sql/sql_select.cc | 107 ++++++++++-------- sql/sql_yacc.yy | 97 ++++++++-------- sql/table.h | 5 +- 11 files changed, 154 insertions(+), 117 deletions(-) diff --git a/mysql-test/suite/versioning/r/optimized_fields.result b/mysql-test/suite/versioning/r/optimized_fields.result index ea5b174f6dd..20fab121a69 100644 --- a/mysql-test/suite/versioning/r/optimized_fields.result +++ b/mysql-test/suite/versioning/r/optimized_fields.result @@ -25,7 +25,7 @@ a b 3 NULL Warnings: Warning 4075 Attempt to read unversioned field `b` in historical query -select count(*) from t group by b for system_time as of timestamp now(6); +select count(*) from t group by b query for system_time as of timestamp now(6); count(*) 2 Warnings: @@ -42,23 +42,23 @@ a b 3 NULL Warnings: Warning 4075 Attempt to read unversioned field `b` in historical query -select * from t group by a having a=2 for system_time as of timestamp now(6); +select * from t group by a having a=2 query for system_time as of timestamp now(6); a b Warnings: Warning 4075 Attempt to read unversioned field `b` in historical query -select * from t group by b having b=2 for system_time as of timestamp now(6); +select * from t group by b having b=2 query for system_time as of timestamp now(6); a b Warnings: Warning 4075 Attempt to read unversioned field `b` in historical query -select a from t where b=2 for system_time as of timestamp now(6); +select a from t where b=2 query for system_time as of timestamp now(6); a Warnings: Warning 4075 Attempt to read unversioned field `b` in historical query -select a from t where b=NULL for system_time as of timestamp now(6); +select a from t where b=NULL query for system_time as of timestamp now(6); a Warnings: Warning 4075 Attempt to read unversioned field `b` in historical query -select count(*), b from t group by b having b=NULL for system_time as of timestamp now(6); +select count(*), b from t group by b having b=NULL query for system_time as of timestamp now(6); count(*) b Warnings: Warning 4075 Attempt to read unversioned field `b` in historical query diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index dad8b394079..72f8e0424d6 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -95,11 +95,11 @@ select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 delete from t1; delete from t2; select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x -for system_time as of timestamp @t0; +query for system_time as of timestamp @t0; select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x -for system_time as of timestamp @t0; +query for system_time as of timestamp @t0; select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x -for system_time as of timestamp @t0; +query for system_time as of timestamp @t0; drop table t1; drop table t2; end~~ diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result index eeec506f933..5fa59b23c47 100644 --- a/mysql-test/suite/versioning/r/view.result +++ b/mysql-test/suite/versioning/r/view.result @@ -23,7 +23,7 @@ x create or replace view vt1 as select * from t1; show create view vt1; View Create View character_set_client collation_connection -vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` where `t1`.`sys_trx_end` = 18446744073709551615 for system_time all latin1 latin1_swedish_ci +vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` where `t1`.`sys_trx_end` = 18446744073709551615 query for system_time all latin1 latin1_swedish_ci drop view vt1; drop view vt2; drop table t1; diff --git a/mysql-test/suite/versioning/t/optimized_fields.test b/mysql-test/suite/versioning/t/optimized_fields.test index 62f245dc28d..02f51423cc1 100644 --- a/mysql-test/suite/versioning/t/optimized_fields.test +++ b/mysql-test/suite/versioning/t/optimized_fields.test @@ -9,14 +9,14 @@ select * from t; select a from t for system_time as of timestamp now(6); select a, b, b+0 from t for system_time as of timestamp now(6); select * from t for system_time as of timestamp now(6); -select count(*) from t group by b for system_time as of timestamp now(6); +select count(*) from t group by b query for system_time as of timestamp now(6); select * from t for system_time as of timestamp now(6) order by b asc; select * from t for system_time as of timestamp now(6) order by b desc; -select * from t group by a having a=2 for system_time as of timestamp now(6); -select * from t group by b having b=2 for system_time as of timestamp now(6); -select a from t where b=2 for system_time as of timestamp now(6); -select a from t where b=NULL for system_time as of timestamp now(6); -select count(*), b from t group by b having b=NULL for system_time as of timestamp now(6); +select * from t group by a having a=2 query for system_time as of timestamp now(6); +select * from t group by b having b=2 query for system_time as of timestamp now(6); +select a from t where b=2 query for system_time as of timestamp now(6); +select a from t where b=NULL query for system_time as of timestamp now(6); +select count(*), b from t group by b having b=NULL query for system_time as of timestamp now(6); select a, b from t; drop table t; diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index d47b09e2205..ca3f8d2b3b7 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -91,11 +91,11 @@ begin delete from t2; select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x - for system_time as of timestamp @t0; + query for system_time as of timestamp @t0; select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x - for system_time as of timestamp @t0; + query for system_time as of timestamp @t0; select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x - for system_time as of timestamp @t0; + query for system_time as of timestamp @t0; drop table t1; drop table t2; diff --git a/sql/item.cc b/sql/item.cc index 4bcdb477a51..bb1efca232b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2762,8 +2762,10 @@ void Item_field::set_field(Field *field_par) field->force_null= false; if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG && context && - context->select_lex && - context->select_lex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) + ((field->table->pos_in_table_list && + field->table->pos_in_table_list->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) || + (context->select_lex && + context->select_lex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED))) { field->force_null= true; push_warning_printf( diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3375324b027..75a4c3bbc0c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -766,6 +766,8 @@ void LEX::start(THD *thd_arg) frame_bottom_bound= NULL; win_spec= NULL; + vers_conditions.empty(); + is_lex_started= TRUE; DBUG_VOID_RETURN; } @@ -1366,6 +1368,19 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) return FOR_SYM; } break; + case QUERY_SYM: + token= lex_one_token(yylval, thd); + lip->add_digest_token(token, yylval); + switch(token) { + case FOR_SYM: + return QUERY_FOR_SYM; + default: + lip->lookahead_yylval= lip->yylval; + lip->yylval= NULL; + lip->lookahead_token= token; + return QUERY_SYM; + } + break; default: break; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c0e28ab8fd2..06aa248ee02 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2920,6 +2920,9 @@ public: Window_frame_bound *frame_bottom_bound; Window_spec *win_spec; + /* System Versioning */ + vers_select_conds_t vers_conditions; + inline void free_set_stmt_mem_root() { DBUG_ASSERT(!is_arena_for_set_stmt()); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6655f71e10a..a00304760de 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -688,13 +688,16 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, { if (table->table && table->table->versioned()) versioned_tables++; + else if (table->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) + { + my_error(ER_VERSIONING_REQUIRED, MYF(0), "`FOR SYSTEM_TIME` query"); + DBUG_RETURN(-1); + } } - vers_range_type_t query_type= slex->vers_conditions.type; - if (versioned_tables == 0) { - if (query_type != FOR_SYSTEM_TIME_UNSPECIFIED) + if (slex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) { my_error(ER_VERSIONING_REQUIRED, MYF(0), "`FOR SYSTEM_TIME` query"); DBUG_RETURN(-1); @@ -702,30 +705,6 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, DBUG_RETURN(0); } - if (query_type != FOR_SYSTEM_TIME_UNSPECIFIED) - { - switch (slex->lock_type) - { - case TL_WRITE_ALLOW_WRITE: - case TL_WRITE_CONCURRENT_INSERT: - case TL_WRITE_DELAYED: - case TL_WRITE_DEFAULT: - case TL_WRITE_LOW_PRIORITY: - case TL_WRITE: - case TL_WRITE_ONLY: - my_error(ER_VERS_WRONG_PARAMS, MYF(0), "FOR SYSTEM_TIME query", "write-locking of historic rows"); - DBUG_RETURN(-1); - default: - break; - } - - if (query_type == FOR_SYSTEM_TIME_ALL) - { - slex->vers_conditions.unwrapped= true; - DBUG_RETURN(0); - } - } - /* For prepared statements we create items on statement arena, because they must outlive execution phase for multiple executions. */ arena= thd->activate_stmt_arena_if_needed(&backup); @@ -779,6 +758,36 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, { if (table->table && table->table->versioned()) { + vers_select_conds_t &vers_conditions= + table->vers_conditions.type == FOR_SYSTEM_TIME_UNSPECIFIED ? + slex->vers_conditions : table->vers_conditions; + + if (vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) + { + switch (slex->lock_type) + { + case TL_WRITE_ALLOW_WRITE: + case TL_WRITE_CONCURRENT_INSERT: + case TL_WRITE_DELAYED: + case TL_WRITE_DEFAULT: + case TL_WRITE_LOW_PRIORITY: + case TL_WRITE: + case TL_WRITE_ONLY: + my_error(ER_VERS_WRONG_PARAMS, MYF(0), "FOR SYSTEM_TIME query", "write-locking of historic rows"); + if (arena) + thd->restore_active_arena(arena, &backup); + DBUG_RETURN(-1); + default: + break; + } + + if (vers_conditions.type == FOR_SYSTEM_TIME_ALL) + { + vers_conditions.unwrapped= true; + continue; + } + } + COND** dst_cond= where_expr; if (table->on_expr) { @@ -798,14 +807,14 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, if (table->table->versioned_by_sql()) { - if (slex->vers_conditions.unit == UNIT_TRX_ID) + if (vers_conditions.unit == UNIT_TRX_ID) { my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name); DBUG_RETURN(-1); } } - else if (vers_simple_select && slex->vers_conditions.unit == UNIT_TIMESTAMP - && query_type != FOR_SYSTEM_TIME_UNSPECIFIED) + else if (vers_simple_select && vers_conditions.unit == UNIT_TIMESTAMP + && vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) { DBUG_ASSERT(table->table->s && table->table->s->db_plugin); handlerton *hton= plugin_hton(table->table->s->db_plugin); @@ -826,7 +835,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, Item *cond1= 0, *cond2= 0, *curr= 0; if (table->table->versioned_by_sql() || vers_simple_select) { - switch (query_type) + switch (vers_conditions.type) { case FOR_SYSTEM_TIME_UNSPECIFIED: if (table->table->versioned_by_sql()) @@ -844,21 +853,21 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, break; case FOR_SYSTEM_TIME_AS_OF: cond1= newx Item_func_le(thd, row_start, - slex->vers_conditions.start); + vers_conditions.start); cond2= newx Item_func_gt(thd, row_end, - slex->vers_conditions.start); + vers_conditions.start); break; case FOR_SYSTEM_TIME_FROM_TO: cond1= newx Item_func_lt(thd, row_start, - slex->vers_conditions.end); + vers_conditions.end); cond2= newx Item_func_ge(thd, row_end, - slex->vers_conditions.start); + vers_conditions.start); break; case FOR_SYSTEM_TIME_BETWEEN: cond1= newx Item_func_le(thd, row_start, - slex->vers_conditions.end); + vers_conditions.end); cond2= newx Item_func_ge(thd, row_end, - slex->vers_conditions.start); + vers_conditions.start); break; default: DBUG_ASSERT(0); @@ -872,33 +881,33 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, Item *trx_id0, *trx_id1; - switch (query_type) + switch (vers_conditions.type) { case FOR_SYSTEM_TIME_UNSPECIFIED: curr= newx Item_int(thd, ULONGLONG_MAX); cond1= newx Item_func_eq(thd, row_end2, curr); break; case FOR_SYSTEM_TIME_AS_OF: - trx_id0= slex->vers_conditions.unit == UNIT_TIMESTAMP ? - newx Item_func_vtq_id(thd, slex->vers_conditions.start, VTQ_TRX_ID) : - slex->vers_conditions.start; + trx_id0= vers_conditions.unit == UNIT_TIMESTAMP ? + newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID) : + vers_conditions.start; cond1= newx Item_func_vtq_trx_sees_eq(thd, trx_id0, row_start); cond2= newx Item_func_vtq_trx_sees(thd, row_end, trx_id0); break; case FOR_SYSTEM_TIME_FROM_TO: case FOR_SYSTEM_TIME_BETWEEN: - if (slex->vers_conditions.unit == UNIT_TIMESTAMP) + if (vers_conditions.unit == UNIT_TIMESTAMP) { - trx_id0= newx Item_func_vtq_id(thd, slex->vers_conditions.start, VTQ_TRX_ID, true); - trx_id1= newx Item_func_vtq_id(thd, slex->vers_conditions.end, VTQ_TRX_ID, false); + trx_id0= newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID, true); + trx_id1= newx Item_func_vtq_id(thd, vers_conditions.end, VTQ_TRX_ID, false); } else { - trx_id0= slex->vers_conditions.start; - trx_id1= slex->vers_conditions.end; + trx_id0= vers_conditions.start; + trx_id1= vers_conditions.end; } - cond1= query_type == FOR_SYSTEM_TIME_FROM_TO ? + cond1= vers_conditions.type == FOR_SYSTEM_TIME_FROM_TO ? newx Item_func_vtq_trx_sees(thd, trx_id1, row_start) : newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start); cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0); @@ -925,9 +934,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, } // for (table= tables; ...) if (arena) - { thd->restore_active_arena(arena, &backup); - } slex->vers_conditions.unwrapped= true; @@ -25554,7 +25561,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) if (vers_conditions.unwrapped) { // versioning conditions are already unwrapped to WHERE clause - str->append(STRING_WITH_LEN(" for system_time all ")); + str->append(STRING_WITH_LEN(" query for system_time all ")); } if (order_list.elements) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4c781a6afd1..11f4b53eb8b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -751,6 +751,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) %} %union { + bool BOOL; int num; ulong ulong_num; ulonglong ulonglong_number; @@ -1352,6 +1353,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token PURGE %token QUARTER_SYM %token QUERY_SYM +%token QUERY_FOR_SYM /* INTERNAL */ %token QUICK %token RAISE_SYM /* Oracle-PLSQL-R */ %token RANGE_SYM /* SQL-2003-R */ @@ -1970,6 +1972,7 @@ END_OF_INPUT %type opt_with_column_list %type trans_or_timestamp +%type opt_for_system_time_clause %% @@ -8762,7 +8765,7 @@ table_expression: opt_group_clause opt_having_clause opt_window_clause - opt_for_system_time_clause + opt_query_for_system_time_clause ; opt_table_expression: @@ -8808,75 +8811,74 @@ trans_or_timestamp: } ; -opt_for_system_time_clause: +opt_query_for_system_time_clause: /* empty */ {} - | FOR_SYSTEM_TIME_SYM - AS OF_SYM - trans_or_timestamp simple_expr + | QUERY_FOR_SYM SYSTEM_TIME_SYM for_system_time_expr { - Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, $4, $5); + DBUG_ASSERT(Select); + Select->vers_conditions= Lex->vers_conditions; } - | FOR_SYSTEM_TIME_SYM - AS OF_SYM - NOW_SYM + ; + +opt_for_system_time_clause: + /* empty */ + { + $$= false; + } + | FOR_SYSTEM_TIME_SYM for_system_time_expr + { + $$= true; + } + ; + +for_system_time_expr: + AS OF_SYM trans_or_timestamp simple_expr + { + Lex->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, $3, $4); + } + | AS OF_SYM NOW_SYM { Item *item= new (thd->mem_root) Item_func_now_local(thd, 6); if (item == NULL) MYSQL_YYABORT; - Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, UNIT_TIMESTAMP, item); + Lex->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, UNIT_TIMESTAMP, item); } - | FOR_SYSTEM_TIME_SYM ALL + | ALL { - Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_ALL, UNIT_TIMESTAMP); + Lex->vers_conditions.init(FOR_SYSTEM_TIME_ALL, UNIT_TIMESTAMP); } - | FOR_SYSTEM_TIME_SYM - FROM - trans_or_timestamp - simple_expr - TO_SYM - trans_or_timestamp - simple_expr + | FROM trans_or_timestamp simple_expr + TO_SYM trans_or_timestamp simple_expr { - if ($3 != $6) + if ($2 != $5) { Lex->parse_error(ER_VERS_RANGE_UNITS_MISMATCH); MYSQL_YYABORT; } - Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $3, $4, $7); + Lex->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $2, $3, $6); } - | FOR_SYSTEM_TIME_SYM - trans_or_timestamp - FROM - simple_expr - TO_SYM - simple_expr + | trans_or_timestamp + FROM simple_expr + TO_SYM simple_expr { - Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $2, $4, $6); + Lex->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $1, $3, $5); } - | FOR_SYSTEM_TIME_SYM - BETWEEN_SYM - trans_or_timestamp - simple_expr - AND_SYM - trans_or_timestamp - simple_expr + | BETWEEN_SYM trans_or_timestamp simple_expr + AND_SYM trans_or_timestamp simple_expr { - if ($3 != $6) + if ($2 != $5) { Lex->parse_error(ER_VERS_RANGE_UNITS_MISMATCH); MYSQL_YYABORT; } - Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $3, $4, $7); + Lex->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $2, $3, $6); } - | FOR_SYSTEM_TIME_SYM - trans_or_timestamp - BETWEEN_SYM - simple_expr - AND_SYM - simple_expr + | trans_or_timestamp + BETWEEN_SYM simple_expr + AND_SYM simple_expr { - Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $2, $4, $6); + Lex->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $1, $3, $5); } ; @@ -11284,10 +11286,11 @@ table_factor: table_primary_ident: { + DBUG_ASSERT(Select); SELECT_LEX *sel= Select; sel->table_join_options= 0; } - table_ident opt_use_partition opt_table_alias opt_key_definition + table_ident opt_use_partition opt_table_alias opt_key_definition opt_for_system_time_clause { if (!($$= Select->add_table_to_list(thd, $2, $4, Select->get_table_join_options(), @@ -11297,6 +11300,8 @@ table_primary_ident: $3))) MYSQL_YYABORT; Select->add_joined_table($$); + if ($6) + $$->vers_conditions= Lex->vers_conditions; } ; @@ -13007,6 +13012,8 @@ truncate: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; + if ($5) + Select->vers_conditions= Lex->vers_conditions; } ; diff --git a/sql/table.h b/sql/table.h index da91162523a..a13de8d7128 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1856,7 +1856,7 @@ enum vers_range_unit_t UNIT_TRX_ID }; -/** System versioning support. */ +/** last_leaf_for_name_resolutioning support. */ struct vers_select_conds_t { vers_range_type_t type; @@ -2344,6 +2344,9 @@ struct TABLE_LIST TABLE_LIST *first_leaf_for_name_resolution(); TABLE_LIST *last_leaf_for_name_resolution(); + /* System Versioning */ + vers_select_conds_t vers_conditions; + /** @brief Find the bottom in the chain of embedded table VIEWs.