summaryrefslogtreecommitdiff
path: root/sql/sql_cte.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_cte.cc')
-rw-r--r--sql/sql_cte.cc34
1 files changed, 29 insertions, 5 deletions
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index 97bbf8f73bd..b05a688f40e 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -743,9 +743,10 @@ bool With_clause::prepare_unreferenced_elements(THD *thd)
@brief
Save the specification of the given with table as a string
- @param thd The context of the statement containing this with element
- @param spec_start The beginning of the specification in the input string
- @param spec_end The end of the specification in the input string
+ @param thd The context of the statement containing this with element
+ @param spec_start The beginning of the specification in the input string
+ @param spec_end The end of the specification in the input string
+ @param spec_offset The offset of the specification in the input string
@details
The method creates for a string copy of the specification used in this
@@ -757,10 +758,17 @@ bool With_clause::prepare_unreferenced_elements(THD *thd)
true on failure
*/
-bool With_element::set_unparsed_spec(THD *thd, char *spec_start, char *spec_end)
+bool With_element::set_unparsed_spec(THD *thd, char *spec_start, char *spec_end,
+ my_ptrdiff_t spec_offset)
{
+ stmt_prepare_mode= thd->m_parser_state->m_lip.stmt_prepare_mode;
unparsed_spec.length= spec_end - spec_start;
- unparsed_spec.str= thd->strmake(spec_start, unparsed_spec.length);
+
+ if (stmt_prepare_mode || !thd->lex->sphead)
+ unparsed_spec.str= spec_start;
+ else
+ unparsed_spec.str= thd->strmake(spec_start, unparsed_spec.length);
+ unparsed_spec_offset= spec_offset;
if (!unparsed_spec.str)
{
@@ -830,13 +838,28 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
TABLE_LIST *spec_tables_tail;
st_select_lex *with_select;
+ char save_end= unparsed_spec.str[unparsed_spec.length];
+ ((char*) &unparsed_spec.str[unparsed_spec.length])[0]= '\0';
if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)unparsed_spec.length))
goto err;
+ parser_state.m_lip.stmt_prepare_mode= stmt_prepare_mode;
+ parser_state.m_lip.multi_statements= false;
+ parser_state.m_lip.m_digest= NULL;
+
lex_start(thd);
+ lex->clone_spec_offset= unparsed_spec_offset;
+ lex->param_list= old_lex->param_list;
+ lex->sphead= old_lex->sphead;
+ lex->spname= old_lex->spname;
+ lex->spcont= old_lex->spcont;
+ lex->sp_chistics= old_lex->sp_chistics;
+
lex->stmt_lex= old_lex;
with_select= &lex->select_lex;
with_select->select_number= ++thd->lex->stmt_lex->current_select_number;
parse_status= parse_sql(thd, &parser_state, 0);
+ ((char*) &unparsed_spec.str[unparsed_spec.length])[0]= save_end;
+
if (parse_status)
goto err;
@@ -881,6 +904,7 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
with_select));
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
res= NULL;
+ lex->sphead= NULL; // in order not to delete lex->sphead
lex_end(lex);
err:
if (arena)