diff options
Diffstat (limited to 'sql/sql_view.cc')
-rw-r--r-- | sql/sql_view.cc | 291 |
1 files changed, 174 insertions, 117 deletions
diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 297edd0d90d..6e27af63e8a 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -24,7 +24,7 @@ #define MD5_BUFF_LENGTH 33 -const LEX_STRING view_type= { (char*) STRING_WITH_LEN("VIEW") }; +const LEX_STRING view_type= { C_STRING_WITH_LEN("VIEW") }; static int mysql_register_view(THD *thd, TABLE_LIST *view, enum_view_create_mode mode); @@ -318,11 +318,11 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, */ if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || + check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || (mode != VIEW_CREATE_NEW && (check_access(thd, DROP_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0)))) + check_grant(thd, DROP_ACL, view, 0, 1, 0)))) { res= TRUE; goto err; @@ -375,7 +375,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, { if (check_access(thd, SELECT_ACL, tbl->db, &tbl->grant.privilege, 0, 0, test(tbl->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) + check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) { res= TRUE; goto err; @@ -554,15 +554,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, { String buff; const LEX_STRING command[3]= - {{(char *)STRING_WITH_LEN("CREATE ")}, - {(char *)STRING_WITH_LEN("ALTER ")}, - {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}}; + {{ C_STRING_WITH_LEN("CREATE ") }, + { C_STRING_WITH_LEN("ALTER ") }, + { C_STRING_WITH_LEN("CREATE OR REPLACE ") }}; buff.append(command[thd->lex->create_view_mode].str, command[thd->lex->create_view_mode].length); view_store_options(thd, views, &buff); buff.append(STRING_WITH_LEN("VIEW ")); - /* Test if user supplied a db (ie: we did not use thd->db) */ if (views->db && views->db[0] && (thd->db == NULL || strcmp(views->db, thd->db))) @@ -578,7 +577,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, List_iterator_fast<LEX_STRING> names(lex->view_list); LEX_STRING *name; int i; - + for (i= 0; (name= names++); i++) { buff.append(i ? ", " : "("); @@ -589,8 +588,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, buff.append(STRING_WITH_LEN(" AS ")); buff.append(views->source.str, views->source.length); - Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::STMT_QUERY_TYPE, + buff.ptr(), buff.length(), FALSE, FALSE); } VOID(pthread_mutex_unlock(&LOCK_open)); @@ -614,8 +613,8 @@ err: /* index of revision number in following table */ static const int revision_number_position= 8; -/* index of last required parameter for making view */ -static const int required_view_parameters= 10; +/* number of required parameters for making view */ +static const int required_view_parameters= 16; /* number of backups */ static const int num_view_backups= 3; @@ -626,42 +625,51 @@ static const int num_view_backups= 3; parse() */ static File_option view_parameters[]= -{{{(char*) STRING_WITH_LEN("query")}, - my_offsetof(TABLE_LIST, query), +{{{ C_STRING_WITH_LEN("query")}, + my_offsetof(TABLE_LIST, select_stmt), FILE_OPTIONS_ESTRING}, - {{(char*) STRING_WITH_LEN("md5")}, + {{ C_STRING_WITH_LEN("md5")}, my_offsetof(TABLE_LIST, md5), FILE_OPTIONS_STRING}, - {{(char*) STRING_WITH_LEN("updatable")}, + {{ C_STRING_WITH_LEN("updatable")}, my_offsetof(TABLE_LIST, updatable_view), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("algorithm")}, + {{ C_STRING_WITH_LEN("algorithm")}, my_offsetof(TABLE_LIST, algorithm), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("definer_user")}, + {{ C_STRING_WITH_LEN("definer_user")}, my_offsetof(TABLE_LIST, definer.user), FILE_OPTIONS_STRING}, - {{(char*) STRING_WITH_LEN("definer_host")}, + {{ C_STRING_WITH_LEN("definer_host")}, my_offsetof(TABLE_LIST, definer.host), FILE_OPTIONS_STRING}, - {{(char*) STRING_WITH_LEN("suid")}, + {{ C_STRING_WITH_LEN("suid")}, my_offsetof(TABLE_LIST, view_suid), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("with_check_option")}, + {{ C_STRING_WITH_LEN("with_check_option")}, my_offsetof(TABLE_LIST, with_check), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("revision")}, + {{ C_STRING_WITH_LEN("revision")}, my_offsetof(TABLE_LIST, revision), FILE_OPTIONS_REV}, - {{(char*) STRING_WITH_LEN("timestamp")}, + {{ C_STRING_WITH_LEN("timestamp")}, my_offsetof(TABLE_LIST, timestamp), FILE_OPTIONS_TIMESTAMP}, - {{(char*)STRING_WITH_LEN("create-version")}, + {{ C_STRING_WITH_LEN("create-version")}, my_offsetof(TABLE_LIST, file_version), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("source")}, + {{ C_STRING_WITH_LEN("source")}, my_offsetof(TABLE_LIST, source), FILE_OPTIONS_ESTRING}, + {{(char*) STRING_WITH_LEN("client_cs_name")}, + my_offsetof(TABLE_LIST, view_client_cs_name), + FILE_OPTIONS_STRING}, + {{(char*) STRING_WITH_LEN("connection_cl_name")}, + my_offsetof(TABLE_LIST, view_connection_cl_name), + FILE_OPTIONS_STRING}, + {{(char*) STRING_WITH_LEN("view_body_utf8")}, + my_offsetof(TABLE_LIST, view_body_utf8), + FILE_OPTIONS_ESTRING}, {{NullS, 0}, 0, FILE_OPTIONS_STRING} }; @@ -689,33 +697,33 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { LEX *lex= thd->lex; char buff[4096]; - String str(buff,(uint32) sizeof(buff), system_charset_info); + String view_query(buff, sizeof (buff), thd->charset()); char md5[MD5_BUFF_LENGTH]; bool can_be_merged; - char dir_buff[FN_REFLEN], file_buff[FN_REFLEN]; - LEX_STRING dir, file; + char dir_buff[FN_REFLEN], path_buff[FN_REFLEN]; + LEX_STRING dir, file, path; int error= 0; DBUG_ENTER("mysql_register_view"); /* print query */ - str.length(0); + view_query.length(0); { ulong sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES; thd->variables.sql_mode&= ~MODE_ANSI_QUOTES; - lex->unit.print(&str); + lex->unit.print(&view_query); thd->variables.sql_mode|= sql_mode; } - DBUG_PRINT("info", ("View: %s", str.ptr())); + DBUG_PRINT("info", ("View: %s", view_query.ptr())); /* fill structure */ - view->query.str= str.c_ptr_safe(); - view->query.length= str.length(); - view->source.str= thd->query + thd->lex->create_view_select_start; - view->source.length= (char *)skip_rear_comments(thd->charset(), - (char *)view->source.str, - (char *)thd->query + - thd->query_length) - - view->source.str; + view->select_stmt.str= view_query.c_ptr_safe(); + view->select_stmt.length= view_query.length(); + + view->source.str= (char*) thd->lex->create_view_select_start; + view->source.length= (thd->lex->create_view_select_end + - thd->lex->create_view_select_start); + trim_whitespace(thd->charset(), & view->source); + view->file_version= 1; view->calc_md5(md5); view->md5.str= md5; @@ -758,15 +766,17 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, } loop_out: /* print file name */ - (void) my_snprintf(dir_buff, FN_REFLEN, "%s/%s/", - mysql_data_home, view->db); - unpack_filename(dir_buff, dir_buff); + dir.length= build_table_filename(dir_buff, sizeof(dir_buff), + view->db, "", "", 0); dir.str= dir_buff; - dir.length= strlen(dir_buff); - file.str= file_buff; - file.length= (strxnmov(file_buff, FN_REFLEN, view->table_name, reg_ext, - NullS) - file_buff); + path.length= build_table_filename(path_buff, sizeof(path_buff), + view->db, view->table_name, reg_ext, 0); + path.str= path_buff; + + file.str= path.str + dir.length; + file.length= path.length - dir.length; + /* init timestamp */ if (!view->timestamp.str) view->timestamp.str= view->timestamp_buffer; @@ -778,7 +788,7 @@ loop_out: File_parser *parser; path.str= path_buff; - fn_format(path_buff, file.str, dir.str, 0, MY_UNPACK_FILENAME); + fn_format(path_buff, file.str, dir.str, "", MY_UNPACK_FILENAME); path.length= strlen(path_buff); if (!access(path.str, F_OK)) @@ -809,7 +819,7 @@ loop_out: TODO: read dependence list, too, to process cascade/restrict TODO: special cascade/restrict procedure for alter? */ - if (parser->parse((gptr)view, thd->mem_root, + if (parser->parse((uchar*)view, thd->mem_root, view_parameters + revision_number_position, 1, &file_parser_dummy_hook)) { @@ -828,6 +838,23 @@ loop_out: } } + /* Initialize view creation context from the environment. */ + + view->view_creation_ctx= View_creation_ctx::create(thd); + + /* + Set LEX_STRING attributes in view-structure for parser to create + frm-file. + */ + + lex_string_set(&view->view_client_cs_name, + view->view_creation_ctx->get_client_cs()->csname); + + lex_string_set(&view->view_connection_cl_name, + view->view_creation_ctx->get_connection_cl()->name); + + view->view_body_utf8= lex->view_body_utf8; + /* Check that table of main select do not used in subqueries. @@ -839,7 +866,7 @@ loop_out: UNION */ if (view->updatable_view && - !lex->select_lex.next_select() && + !lex->select_lex.master_unit()->is_union() && !((TABLE_LIST*)lex->select_lex.table_list.first)->next_local && find_table_in_global_list(lex->query_tables->next_global, lex->query_tables->db, @@ -857,15 +884,15 @@ loop_out: } if (sql_create_definition_file(&dir, &file, view_file_type, - (gptr)view, view_parameters, num_view_backups)) + (uchar*)view, view_parameters, num_view_backups)) { error= thd->net.report_error? -1 : 1; goto err; } DBUG_RETURN(0); err: - view->query.str= NULL; - view->query.length= 0; + view->select_stmt.str= NULL; + view->select_stmt.length= 0; view->md5.str= NULL; view->md5.length= 0; DBUG_RETURN(error); @@ -894,9 +921,10 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, LEX *old_lex, *lex; Query_arena *arena, backup; TABLE_LIST *top_view= table->top_table(); - int res; + bool parse_status; bool result, view_is_mergeable; TABLE_LIST *view_main_select_tables; + DBUG_ENTER("mysql_make_view"); DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name)); @@ -922,12 +950,9 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, DBUG_RETURN(0); } - if (table->use_index || table->ignore_index) + if (table->index_hints && table->index_hints->elements) { - my_error(ER_WRONG_USAGE, MYF(0), - table->ignore_index ? "IGNORE INDEX" : - (table->force_index ? "FORCE INDEX" : "USE INDEX"), - "VIEW"); + my_error(ER_WRONG_USAGE, MYF(0), "index hints", "VIEW"); DBUG_RETURN(TRUE); } @@ -972,7 +997,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, TODO: when VIEWs will be stored in cache, table mem_root should be used here */ - if (parser->parse((gptr)table, thd->mem_root, view_parameters, + if (parser->parse((uchar*)table, thd->mem_root, view_parameters, required_view_parameters, &file_parser_dummy_hook)) goto err; @@ -1006,6 +1031,14 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, /*TODO: md5 test here and warning if it is differ */ /* + Initialize view definition context by character set names loaded from + the view definition file. Use UTF8 character set if view definition + file is of old version and does not contain the character set names. + */ + + table->view_creation_ctx= View_creation_ctx::create(thd, table); + + /* TODO: TABLE mem root should be used here when VIEW will be stored in TABLE cache @@ -1017,21 +1050,23 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, char old_db_buf[NAME_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; - Lex_input_stream lip(thd, table->query.str, table->query.length); - thd->m_lip= &lip; + Lex_input_stream lip(thd, + table->select_stmt.str, + table->select_stmt.length); /* Use view db name as thread default database, in order to ensure that the view is parsed and prepared correctly. */ - if ((result= sp_use_new_db(thd, table->view_db, &old_db, 1, &dbchanged))) + if ((result= mysql_opt_change_db(thd, &table->view_db, &old_db, 1, + &dbchanged))) goto end; lex_start(thd); view_select= &lex->select_lex; view_select->select_number= ++thd->select_number; - ulong save_mode= thd->variables.sql_mode; + ulong saved_mode= thd->variables.sql_mode; /* switch off modes which can prevent normal parsing of VIEW - MODE_REAL_AS_FLOAT affect only CREATE TABLE parsing + MODE_PIPES_AS_CONCAT affect expression parsing @@ -1058,21 +1093,23 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, */ thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES); - CHARSET_INFO *save_cs= thd->variables.character_set_client; - thd->variables.character_set_client= system_charset_info; - res= MYSQLparse((void *)thd); + + /* Parse the query. */ + + parse_status= parse_sql(thd, &lip, table->view_creation_ctx); + + /* Restore environment. */ if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) || (old_lex->sql_command == SQLCOM_SHOW_CREATE)) lex->sql_command= old_lex->sql_command; - thd->variables.character_set_client= save_cs; - thd->variables.sql_mode= save_mode; + thd->variables.sql_mode= saved_mode; if (dbchanged && mysql_change_db(thd, &old_db, TRUE)) goto err; } - if (!res && !thd->is_fatal_error) + if (!parse_status) { TABLE_LIST *view_tables= lex->query_tables; TABLE_LIST *view_tables_tail= 0; @@ -1155,6 +1192,12 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, table->next_global= view_tables; } + /* + If the view's body needs row-based binlogging (e.g. the VIEW is created + from SELECT UUID()), the top statement also needs it. + */ + if (lex->is_stmt_unsafe()) + old_lex->set_stmt_unsafe(); view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE && lex->can_be_merged()); LINT_INIT(view_main_select_tables); @@ -1379,11 +1422,11 @@ ok: (st_select_lex_node**)&old_lex->all_selects_list; ok2: - if (!old_lex->time_zone_tables_used && thd->lex->time_zone_tables_used) - old_lex->time_zone_tables_used= thd->lex->time_zone_tables_used; + DBUG_ASSERT(lex == thd->lex); + thd->lex= old_lex; // Needed for prepare_security result= !table->prelocking_placeholder && table->prepare_security(thd); - lex_end(thd->lex); + lex_end(lex); end: if (arena) thd->restore_active_arena(arena, &backup); @@ -1416,22 +1459,22 @@ err: bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) { - DBUG_ENTER("mysql_drop_view"); char path[FN_REFLEN]; TABLE_LIST *view; - frm_type_enum type; - db_type not_used; String non_existant_views; char *wrong_object_db= NULL, *wrong_object_name= NULL; bool error= FALSE; + enum legacy_db_type not_used; + DBUG_ENTER("mysql_drop_view"); VOID(pthread_mutex_lock(&LOCK_open)); for (view= views; view; view= view->next_local) { - strxnmov(path, FN_REFLEN, mysql_data_home, "/", view->db, "/", - view->table_name, reg_ext, NullS); - (void) unpack_filename(path, path); - type= FRMTYPE_ERROR; + TABLE_SHARE *share; + frm_type_enum type= FRMTYPE_ERROR; + build_table_filename(path, sizeof(path), + view->db, view->table_name, reg_ext, 0); + if (access(path, F_OK) || FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used))) { @@ -1462,34 +1505,47 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) } if (my_delete(path, MYF(MY_WME))) error= TRUE; + + /* + For a view, there is only one table_share object which should never + be used outside of LOCK_open + */ + if ((share= get_cached_table_share(view->db, view->table_name))) + { + DBUG_ASSERT(share->ref_count == 0); + pthread_mutex_lock(&share->mutex); + share->ref_count++; + share->version= 0; + pthread_mutex_unlock(&share->mutex); + release_table_share(share, RELEASE_WAIT_FOR_DROP); + } query_cache_invalidate3(thd, view, 0); sp_cache_invalidate(); } - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } - - VOID(pthread_mutex_unlock(&LOCK_open)); if (error) { + VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(TRUE); } if (wrong_object_name) { + VOID(pthread_mutex_unlock(&LOCK_open)); my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name, "VIEW"); DBUG_RETURN(TRUE); } if (non_existant_views.length()) { + VOID(pthread_mutex_unlock(&LOCK_open)); my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr()); DBUG_RETURN(TRUE); } + + write_bin_log(thd, TRUE, thd->query, thd->query_length); + send_ok(thd); + VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(FALSE); } @@ -1507,7 +1563,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) FRMTYPE_VIEW view */ -frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt) +frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) { File file; uchar header[10]; //"TYPE=VIEW\n" it is 10 characters @@ -1518,7 +1574,7 @@ frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt) if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) DBUG_RETURN(FRMTYPE_ERROR); - error= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME | MY_NABP)); + error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_WME | MY_NABP)); my_close(file, MYF(MY_WME)); if (error) @@ -1536,7 +1592,7 @@ frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt) (header[2] < FRM_VER+3 || header[2] > FRM_VER+4))) DBUG_RETURN(FRMTYPE_TABLE); - *dbt= ha_checktype(thd, (enum db_type) (uint) *(header + 3), 0, 0); + *dbt= (enum legacy_db_type) (uint) *(header + 3); DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table } @@ -1550,8 +1606,8 @@ frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt) view view for check with opened table DESCRIPTION - If it is VIEW and query have LIMIT clause then check that undertlying - table of viey contain one of following: + If it is VIEW and query have LIMIT clause then check that underlying + table of view contain one of following: 1) primary key of underlying table 2) unique key underlying table with fields for which NULL value is impossible @@ -1591,17 +1647,19 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view) this operation should not have influence on Field::query_id, to avoid marking as used fields which are not used */ - bool save_set_query_id= thd->set_query_id; - thd->set_query_id= 0; + enum_mark_columns save_mark_used_columns= thd->mark_used_columns; + thd->mark_used_columns= MARK_COLUMNS_NONE; + DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); for (Field_translator *fld= trans; fld < end_of_trans; fld++) { if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item)) { - thd->set_query_id= save_set_query_id; + thd->mark_used_columns= save_mark_used_columns; return TRUE; } } - thd->set_query_id= save_set_query_id; + thd->mark_used_columns= save_mark_used_columns; + DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); } /* Loop over all keys to see if a unique-not-null key is used */ for (;key_info != key_info_end ; key_info++) @@ -1750,25 +1808,23 @@ mysql_rename_view(THD *thd, const char *new_name, TABLE_LIST *view) { - LEX_STRING pathstr, file; + LEX_STRING pathstr; File_parser *parser; - char view_path[FN_REFLEN]; + char path_buff[FN_REFLEN]; bool error= TRUE; - DBUG_ENTER("mysql_rename_view"); - strxnmov(view_path, FN_REFLEN, mysql_data_home, "/", view->db, "/", - view->table_name, reg_ext, NullS); - (void) unpack_filename(view_path, view_path); - - pathstr.str= (char *)view_path; - pathstr.length= strlen(view_path); + pathstr.str= (char *) path_buff; + pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1, + view->db, view->table_name, + reg_ext, 0); if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) && is_equal(&view_type, parser->type())) { TABLE_LIST view_def; - char dir_buff[FN_REFLEN], file_buff[FN_REFLEN]; + char dir_buff[FN_REFLEN]; + LEX_STRING dir, file; /* To be PS-friendly we should either to restore state of @@ -1781,7 +1837,7 @@ mysql_rename_view(THD *thd, view_def.view_suid= TRUE; /* get view definition and source */ - if (parser->parse((gptr)&view_def, thd->mem_root, view_parameters, + if (parser->parse((uchar*)&view_def, thd->mem_root, view_parameters, array_elements(view_parameters)-1, &file_parser_dummy_hook)) goto err; @@ -1791,18 +1847,19 @@ mysql_rename_view(THD *thd, view_def.revision - 1, num_view_backups)) goto err; - strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS); - (void) unpack_filename(dir_buff, dir_buff); + dir.str= dir_buff; + dir.length= build_table_filename(dir_buff, sizeof(dir_buff) - 1, + view->db, "", "", 0); - pathstr.str= (char*)dir_buff; - pathstr.length= strlen(dir_buff); + pathstr.str= path_buff; + pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1, + view->db, new_name, reg_ext, 0); - file.str= file_buff; - file.length= (strxnmov(file_buff, FN_REFLEN, new_name, reg_ext, NullS) - - file_buff); + file.str= pathstr.str + dir.length; + file.length= pathstr.length - dir.length; - if (sql_create_definition_file(&pathstr, &file, view_file_type, - (gptr)&view_def, view_parameters, + if (sql_create_definition_file(&dir, &file, view_file_type, + (uchar*)&view_def, view_parameters, num_view_backups)) { /* restore renamed view in case of error */ |