diff options
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r-- | sql/sql_lex.cc | 128 |
1 files changed, 75 insertions, 53 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e93ba7fc10f..65257c9b2ce 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -29,6 +29,7 @@ #include "sp_head.h" #include "sp.h" #include "sql_select.h" +#include "sql_cte.h" static int lex_one_token(YYSTYPE *yylval, THD *thd); @@ -668,11 +669,15 @@ void lex_start(THD *thd) /* 'parent_lex' is used in init_query() so it must be before it. */ lex->select_lex.parent_lex= lex; lex->select_lex.init_query(); + lex->curr_with_clause= 0; + lex->with_clauses_list= 0; + lex->with_clauses_list_last_next= &lex->with_clauses_list; lex->value_list.empty(); lex->update_list.empty(); lex->set_var_list.empty(); lex->param_list.empty(); lex->view_list.empty(); + lex->with_column_list.empty(); lex->with_persistent_for_clause= FALSE; lex->column_list= NULL; lex->index_list= NULL; @@ -1406,28 +1411,22 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) if (use_mb(cs)) { result_state= IDENT_QUOTED; - if (my_mbcharlen(cs, lip->yyGetLast()) > 1) + int char_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (char_length <= 0) { - int l = my_ismbchar(cs, - lip->get_ptr() -1, - lip->get_end_of_query()); - if (l == 0) { - state = MY_LEX_CHAR; - continue; - } - lip->skip_binary(l - 1); + state= MY_LEX_CHAR; + continue; } + lip->skip_binary(char_length - 1); + while (ident_map[c=lip->yyGet()]) { - if (my_mbcharlen(cs, c) > 1) - { - int l; - if ((l = my_ismbchar(cs, - lip->get_ptr() -1, - lip->get_end_of_query())) == 0) - break; - lip->skip_binary(l-1); - } + char_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (char_length <= 0) + break; + lip->skip_binary(char_length - 1); } } else @@ -1568,15 +1567,11 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) result_state= IDENT_QUOTED; while (ident_map[c=lip->yyGet()]) { - if (my_mbcharlen(cs, c) > 1) - { - int l; - if ((l = my_ismbchar(cs, - lip->get_ptr() -1, - lip->get_end_of_query())) == 0) - break; - lip->skip_binary(l-1); - } + int char_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (char_length <= 0) + break; + lip->skip_binary(char_length - 1); } } else @@ -1604,8 +1599,9 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) char quote_char= c; // Used char while ((c=lip->yyGet())) { - int var_length; - if ((var_length= my_mbcharlen(cs, c)) == 1) + int var_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (var_length == 1) { if (c == quote_char) { @@ -1617,11 +1613,9 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) } } #ifdef USE_MB - else if (use_mb(cs)) + else if (var_length > 1) { - if ((var_length= my_ismbchar(cs, lip->get_ptr() - 1, - lip->get_end_of_query()))) - lip->skip_binary(var_length-1); + lip->skip_binary(var_length - 1); } #endif } @@ -2076,6 +2070,9 @@ void st_select_lex_unit::init_query() found_rows_for_union= 0; insert_table_with_stored_vcol= 0; derived= 0; + with_clause= 0; + with_element= 0; + columns_are_renamed= false; } void st_select_lex::init_query() @@ -2259,6 +2256,37 @@ void st_select_lex_node::fast_exclude() } +/** + @brief + Insert a new chain of nodes into another chain before a particular link + + @param in/out + ptr_pos_to_insert the address of the chain pointer pointing to the link + before which the subchain has to be inserted + @param + end_chain_node the last link of the subchain to be inserted + + @details + The method inserts the chain of nodes starting from this node and ending + with the node nd_chain_node into another chain of nodes before the node + pointed to by *ptr_pos_to_insert. + It is assumed that ptr_pos_to_insert belongs to the chain where we insert. + So it must be updated. + + @retval + The method returns the pointer to the first link of the inserted chain +*/ + +st_select_lex_node *st_select_lex_node:: insert_chain_before( + st_select_lex_node **ptr_pos_to_insert, + st_select_lex_node *end_chain_node) +{ + end_chain_node->link_next= *ptr_pos_to_insert; + (*ptr_pos_to_insert)->link_prev= &end_chain_node->link_next; + this->link_prev= ptr_pos_to_insert; + return this; +} + /* Exclude a node from the tree lex structure, but leave it in the global list of nodes. @@ -2648,6 +2676,8 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) void st_select_lex_unit::print(String *str, enum_query_type query_type) { bool union_all= !union_distinct; + if (with_clause) + with_clause->print(str, query_type); for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { if (sl != first_select()) @@ -2688,30 +2718,22 @@ void st_select_lex::print_order(String *str, { if (order->counter_used) { - if (query_type != QT_VIEW_INTERNAL) + char buffer[20]; + size_t length= my_snprintf(buffer, 20, "%d", order->counter); + str->append(buffer, (uint) length); + } + else + { + /* replace numeric reference with equivalent for ORDER constant */ + if (order->item[0]->type() == Item::INT_ITEM && + order->item[0]->basic_const_item()) { - char buffer[20]; - size_t length= my_snprintf(buffer, 20, "%d", order->counter); - str->append(buffer, (uint) length); + /* make it expression instead of integer constant */ + str->append(STRING_WITH_LEN("''")); } else - { - /* replace numeric reference with expression */ - if (order->item[0]->type() == Item::INT_ITEM && - order->item[0]->basic_const_item()) - { - char buffer[20]; - size_t length= my_snprintf(buffer, 20, "%d", order->counter); - str->append(buffer, (uint) length); - /* make it expression instead of integer constant */ - str->append(STRING_WITH_LEN("+0")); - } - else - (*order->item)->print(str, query_type); - } + (*order->item)->print(str, query_type); } - else - (*order->item)->print(str, query_type); if (!order->asc) str->append(STRING_WITH_LEN(" desc")); if (order->next) |