diff options
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 863e7a36aab..2580c8816fd 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1133,7 +1133,7 @@ static bool mysql_test_insert(Prepared_statement *stmt, If we would use locks, then we have to ensure we are not using TL_WRITE_DELAYED as having two such locks can cause table corruption. */ - if (open_normal_and_derived_tables(thd, table_list, 0)) + if (open_normal_and_derived_tables(thd, table_list, 0, DT_INIT)) goto error; if ((values= its++)) @@ -1217,7 +1217,10 @@ static int mysql_test_update(Prepared_statement *stmt, open_tables(thd, &table_list, &table_count, 0)) goto error; - if (table_list->multitable_view) + if (mysql_handle_derived(thd->lex, DT_INIT)) + goto error; + + if (table_list->is_multitable()) { DBUG_ASSERT(table_list->view != 0); DBUG_PRINT("info", ("Switch to multi-update")); @@ -1231,8 +1234,15 @@ static int mysql_test_update(Prepared_statement *stmt, thd->fill_derived_tables() is false here for sure (because it is preparation of PS, so we even do not check it). */ - if (mysql_handle_derived(thd->lex, &mysql_derived_prepare)) + if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT) || + table_list->handle_derived(thd->lex, DT_PREPARE)) + goto error; + + if (!table_list->updatable) + { + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); goto error; + } #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Force privilege re-checking for views after they have been opened. */ @@ -1286,12 +1296,18 @@ error: static bool mysql_test_delete(Prepared_statement *stmt, TABLE_LIST *table_list) { + uint table_count= 0; THD *thd= stmt->thd; LEX *lex= stmt->lex; DBUG_ENTER("mysql_test_delete"); if (delete_precheck(thd, table_list) || - open_normal_and_derived_tables(thd, table_list, 0)) + open_tables(thd, &table_list, &table_count, 0)) + goto error; + + if (mysql_handle_derived(thd->lex, DT_INIT) || + mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) || + mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE)) goto error; if (!table_list->table) @@ -1349,7 +1365,8 @@ static int mysql_test_select(Prepared_statement *stmt, goto error; } - if (open_normal_and_derived_tables(thd, tables, 0)) + if (open_normal_and_derived_tables(thd, tables, 0, + DT_PREPARE | DT_CREATE)) goto error; thd->used_tables= 0; // Updated by setup_fields @@ -1410,7 +1427,8 @@ static bool mysql_test_do_fields(Prepared_statement *stmt, if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) DBUG_RETURN(TRUE); - if (open_normal_and_derived_tables(thd, tables, 0)) + if (open_normal_and_derived_tables(thd, tables, 0, + DT_PREPARE | DT_CREATE)) DBUG_RETURN(TRUE); DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0)); } @@ -1440,7 +1458,8 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, if ((tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) || - open_normal_and_derived_tables(thd, tables, 0)) + open_normal_and_derived_tables(thd, tables, 0, + DT_PREPARE | DT_CREATE)) goto error; while ((var= it++)) @@ -1477,7 +1496,7 @@ static bool mysql_test_call_fields(Prepared_statement *stmt, if ((tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) || - open_normal_and_derived_tables(thd, tables, 0)) + open_normal_and_derived_tables(thd, tables, 0, DT_PREPARE)) goto err; while ((item= it++)) @@ -1552,6 +1571,7 @@ select_like_stmt_test_with_open(Prepared_statement *stmt, int (*specific_prepare)(THD *thd), ulong setup_tables_done_option) { + uint table_count= 0; DBUG_ENTER("select_like_stmt_test_with_open"); /* @@ -1560,7 +1580,8 @@ select_like_stmt_test_with_open(Prepared_statement *stmt, prepared EXPLAIN yet so derived tables will clean up after themself. */ - if (open_normal_and_derived_tables(stmt->thd, tables, 0)) + THD *thd= stmt->thd; + if (open_tables(thd, &tables, &table_count, 0)) DBUG_RETURN(TRUE); DBUG_RETURN(select_like_stmt_test(stmt, specific_prepare, @@ -1605,7 +1626,8 @@ static bool mysql_test_create_table(Prepared_statement *stmt) create_table->skip_temporary= true; } - if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0)) + if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0, + DT_PREPARE | DT_CREATE)) DBUG_RETURN(TRUE); if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) @@ -1623,7 +1645,8 @@ static bool mysql_test_create_table(Prepared_statement *stmt) we validate metadata of all CREATE TABLE statements, which keeps metadata validation code simple. */ - if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0)) + if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0, + DT_PREPARE)) DBUG_RETURN(TRUE); } @@ -1658,7 +1681,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt) if (create_view_precheck(thd, tables, view, lex->create_view_mode)) goto err; - if (open_normal_and_derived_tables(thd, tables, 0)) + if (open_normal_and_derived_tables(thd, tables, 0, DT_PREPARE)) goto err; lex->view_prepare_mode= 1; @@ -2349,6 +2372,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) /* Fix ORDER list */ for (order= (ORDER *)sl->order_list.first; order; order= order->next) order->item= &order->item_ptr; + sl->handle_derived(lex, DT_REINIT); /* clear the no_error flag for INSERT/UPDATE IGNORE */ sl->no_error= FALSE; @@ -2392,9 +2416,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) } lex->current_select= &lex->select_lex; - /* restore original list used in INSERT ... SELECT */ - if (lex->leaf_tables_insert) - lex->select_lex.leaf_tables= lex->leaf_tables_insert; if (lex->result) { |