summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2016-04-09 17:03:48 +0200
committerVladislav Vaintroub <wlad@mariadb.com>2016-04-09 17:03:48 +0200
commitcd776fedba3e2902bc25ee206d6e6266e7eb9411 (patch)
tree95bf82d0e0522c6af708cd28639c82e004b5a264 /sql/sql_lex.cc
parentf884d233e6a5f68bab846a7bdbd041fc4415ad77 (diff)
parentd516a2ae0cbd09d3b5b1667ec62b421330ab9902 (diff)
downloadmariadb-git-10.2-connector-c-integ.tar.gz
Merge branch '10.2' into 10.2-connector-c-integ10.2-connector-c-integ
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r--sql/sql_lex.cc128
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)