diff options
Diffstat (limited to 'sql/sql_cte.cc')
-rw-r--r-- | sql/sql_cte.cc | 34 |
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) |