2004-07-16 00:15:55 +02:00
|
|
|
/* Copyright (C) 2004 MySQL AB
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2006-03-10 01:44:08 +01:00
|
|
|
#define MYSQL_LEX 1
|
2004-07-16 00:15:55 +02:00
|
|
|
#include "mysql_priv.h"
|
|
|
|
#include "sql_select.h"
|
|
|
|
#include "parse_file.h"
|
2004-07-16 14:20:51 +02:00
|
|
|
#include "sp.h"
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
#include "sp_head.h"
|
2005-07-06 18:00:17 +02:00
|
|
|
#include "sp_cache.h"
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2004-10-28 18:37:25 +02:00
|
|
|
#define MD5_BUFF_LENGTH 33
|
|
|
|
|
2005-07-31 11:49:55 +02:00
|
|
|
const LEX_STRING view_type= { (char*) STRING_WITH_LEN("VIEW") };
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|
|
|
enum_view_create_mode mode);
|
|
|
|
|
2004-10-07 11:13:42 +02:00
|
|
|
const char *updatable_views_with_limit_names[]= { "NO", "YES", NullS };
|
|
|
|
TYPELIB updatable_views_with_limit_typelib=
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-10-07 11:13:42 +02:00
|
|
|
array_elements(updatable_views_with_limit_names)-1, "",
|
2004-11-03 11:39:38 +01:00
|
|
|
updatable_views_with_limit_names,
|
|
|
|
0
|
2004-07-16 00:15:55 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-06-21 19:30:48 +02:00
|
|
|
/*
|
|
|
|
Make a unique name for an anonymous view column
|
|
|
|
SYNOPSIS
|
|
|
|
target reference to the item for which a new name has to be made
|
|
|
|
item_list list of items within which we should check uniqueness of
|
|
|
|
the created name
|
|
|
|
last_element the last element of the list above
|
|
|
|
|
|
|
|
NOTE
|
|
|
|
Unique names are generated by adding 'My_exp_' to the old name of the
|
|
|
|
column. In case the name that was created this way already exists, we
|
|
|
|
add a numeric postfix to its end (i.e. "1") and increase the number
|
|
|
|
until the name becomes unique. If the generated name is longer than
|
|
|
|
NAME_LEN, it is truncated.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void make_unique_view_field_name(Item *target,
|
|
|
|
List<Item> &item_list,
|
|
|
|
Item *last_element)
|
|
|
|
{
|
|
|
|
char *name= (target->orig_name ?
|
|
|
|
target->orig_name :
|
|
|
|
target->name);
|
2005-07-04 02:42:33 +02:00
|
|
|
uint name_len, attempt;
|
2005-06-21 19:30:48 +02:00
|
|
|
char buff[NAME_LEN+1];
|
2005-07-04 02:42:33 +02:00
|
|
|
List_iterator_fast<Item> itc(item_list);
|
|
|
|
|
|
|
|
for (attempt= 0;; attempt++)
|
2005-06-21 19:30:48 +02:00
|
|
|
{
|
|
|
|
Item *check;
|
|
|
|
bool ok= TRUE;
|
|
|
|
|
|
|
|
if (attempt)
|
|
|
|
name_len= my_snprintf(buff, NAME_LEN, "My_exp_%d_%s", attempt, name);
|
|
|
|
else
|
|
|
|
name_len= my_snprintf(buff, NAME_LEN, "My_exp_%s", name);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
check= itc++;
|
|
|
|
if (check != target &&
|
|
|
|
my_strcasecmp(system_charset_info, buff, check->name) == 0)
|
|
|
|
{
|
|
|
|
ok= FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (check != last_element);
|
|
|
|
if (ok)
|
|
|
|
break;
|
2005-07-04 02:42:33 +02:00
|
|
|
itc.rewind();
|
2005-06-21 19:30:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
target->orig_name= target->name;
|
|
|
|
target->set_name(buff, name_len, system_charset_info);
|
|
|
|
}
|
|
|
|
|
2005-08-10 15:45:00 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
Check if items with same names are present in list and possibly
|
|
|
|
generate unique names for them.
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
item_list list of Items which should be checked for duplicates
|
|
|
|
gen_unique_view_name flag: generate unique name or return with error when
|
|
|
|
duplicate names are found.
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
This function is used on view creation and preparation of derived tables.
|
|
|
|
It checks item_list for items with duplicate names. If it founds two
|
|
|
|
items with same name and conversion to unique names isn't allowed, or
|
|
|
|
names for both items are set by user - function fails.
|
|
|
|
Otherwise it generates unique name for one item with autogenerated name
|
|
|
|
using make_unique_view_field_name()
|
|
|
|
|
|
|
|
RETURN VALUE
|
|
|
|
FALSE no duplicate names found, or they are converted to unique ones
|
|
|
|
TRUE duplicate names are found and they can't be converted or conversion
|
|
|
|
isn't allowed
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool check_duplicate_names(List<Item> &item_list, bool gen_unique_view_name)
|
|
|
|
{
|
2005-08-18 02:12:42 +02:00
|
|
|
Item *item;
|
|
|
|
List_iterator_fast<Item> it(item_list);
|
|
|
|
List_iterator_fast<Item> itc(item_list);
|
2005-08-10 15:45:00 +02:00
|
|
|
DBUG_ENTER("check_duplicate_names");
|
2005-08-18 02:12:42 +02:00
|
|
|
|
|
|
|
while ((item= it++))
|
2005-08-10 15:45:00 +02:00
|
|
|
{
|
2005-08-18 02:12:42 +02:00
|
|
|
Item *check;
|
|
|
|
/* treat underlying fields like set by user names */
|
|
|
|
if (item->real_item()->type() == Item::FIELD_ITEM)
|
|
|
|
item->is_autogenerated_name= FALSE;
|
|
|
|
itc.rewind();
|
|
|
|
while ((check= itc++) && check != item)
|
2005-08-10 15:45:00 +02:00
|
|
|
{
|
2005-08-18 02:12:42 +02:00
|
|
|
if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
|
2005-08-10 15:45:00 +02:00
|
|
|
{
|
2005-08-18 02:12:42 +02:00
|
|
|
if (!gen_unique_view_name)
|
|
|
|
goto err;
|
|
|
|
if (item->is_autogenerated_name)
|
|
|
|
make_unique_view_field_name(item, item_list, item);
|
|
|
|
else if (check->is_autogenerated_name)
|
|
|
|
make_unique_view_field_name(check, item_list, item);
|
|
|
|
else
|
|
|
|
goto err;
|
2005-08-10 15:45:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DBUG_RETURN(FALSE);
|
2005-08-18 02:12:42 +02:00
|
|
|
|
|
|
|
err:
|
|
|
|
my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
|
|
|
|
DBUG_RETURN(TRUE);
|
2005-08-10 15:45:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
|
|
|
Creating/altering VIEW procedure
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mysql_create_view()
|
|
|
|
thd - thread handler
|
|
|
|
mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
|
|
|
|
|
|
|
|
RETURN VALUE
|
2004-10-20 03:04:37 +02:00
|
|
|
FALSE OK
|
|
|
|
TRUE Error
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2004-09-11 22:52:55 +02:00
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
bool mysql_create_view(THD *thd,
|
|
|
|
enum_view_create_mode mode)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
LEX *lex= thd->lex;
|
|
|
|
bool link_to_local;
|
|
|
|
/* first table in list is target VIEW name => cut off it */
|
|
|
|
TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
|
|
|
|
TABLE_LIST *tables= lex->query_tables;
|
2004-07-16 22:44:14 +02:00
|
|
|
TABLE_LIST *tbl;
|
2004-11-17 13:17:09 +01:00
|
|
|
SELECT_LEX *select_lex= &lex->select_lex;
|
|
|
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
|
|
SELECT_LEX *sl;
|
|
|
|
#endif
|
2004-07-16 00:15:55 +02:00
|
|
|
SELECT_LEX_UNIT *unit= &lex->unit;
|
2004-10-20 03:04:37 +02:00
|
|
|
bool res= FALSE;
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_ENTER("mysql_create_view");
|
|
|
|
|
2004-09-02 11:09:26 +02:00
|
|
|
if (lex->proc_list.first ||
|
|
|
|
lex->result)
|
|
|
|
{
|
|
|
|
my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), (lex->result ?
|
|
|
|
"INTO" :
|
|
|
|
"PROCEDURE"));
|
2004-10-20 03:04:37 +02:00
|
|
|
res= TRUE;
|
2004-09-02 11:09:26 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
if (lex->derived_tables ||
|
2004-07-16 00:15:55 +02:00
|
|
|
lex->variables_used || lex->param_list.elements)
|
|
|
|
{
|
2004-11-12 13:34:00 +01:00
|
|
|
int err= (lex->derived_tables ?
|
2004-09-02 11:09:26 +02:00
|
|
|
ER_VIEW_SELECT_DERIVED :
|
2004-11-12 13:34:00 +01:00
|
|
|
ER_VIEW_SELECT_VARIABLE);
|
|
|
|
my_message(err, ER(err), MYF(0));
|
2004-10-20 03:04:37 +02:00
|
|
|
res= TRUE;
|
2004-07-16 00:15:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2005-07-06 18:00:17 +02:00
|
|
|
if (mode != VIEW_CREATE_NEW)
|
|
|
|
sp_cache_invalidate();
|
|
|
|
|
2006-03-01 12:13:07 +01:00
|
|
|
if (!lex->definer)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
DEFINER-clause is missing; we have to create default definer in
|
|
|
|
persistent arena to be PS/SP friendly.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Query_arena original_arena;
|
|
|
|
Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
|
|
|
|
|
|
|
|
if (!(lex->definer= create_default_definer(thd)))
|
|
|
|
res= TRUE;
|
|
|
|
|
|
|
|
if (ps_arena)
|
|
|
|
thd->restore_active_arena(ps_arena, &original_arena);
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
2005-09-14 09:53:09 +02:00
|
|
|
/*
|
|
|
|
check definer of view:
|
|
|
|
- same as current user
|
|
|
|
- current user has SUPER_ACL
|
|
|
|
*/
|
2005-11-10 20:25:03 +01:00
|
|
|
if (strcmp(lex->definer->user.str,
|
2005-09-15 21:29:07 +02:00
|
|
|
thd->security_ctx->priv_user) != 0 ||
|
2005-09-14 09:53:09 +02:00
|
|
|
my_strcasecmp(system_charset_info,
|
2005-11-10 20:25:03 +01:00
|
|
|
lex->definer->host.str,
|
2005-09-15 21:29:07 +02:00
|
|
|
thd->security_ctx->priv_host) != 0)
|
2005-09-14 09:53:09 +02:00
|
|
|
{
|
2005-09-15 21:29:07 +02:00
|
|
|
if (!(thd->security_ctx->master_access & SUPER_ACL))
|
2005-09-14 09:53:09 +02:00
|
|
|
{
|
2005-11-10 20:25:03 +01:00
|
|
|
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
|
2005-09-14 09:53:09 +02:00
|
|
|
res= TRUE;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-11-10 20:25:03 +01:00
|
|
|
if (!is_acl_user(lex->definer->host.str,
|
|
|
|
lex->definer->user.str))
|
2005-09-14 09:53:09 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
|
|
|
ER_NO_SUCH_USER,
|
|
|
|
ER(ER_NO_SUCH_USER),
|
2005-11-10 20:25:03 +01:00
|
|
|
lex->definer->user.str,
|
|
|
|
lex->definer->host.str);
|
2005-09-14 09:53:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-10-07 00:45:06 +02:00
|
|
|
/*
|
|
|
|
Privilege check for view creation:
|
2005-04-02 17:45:44 +02:00
|
|
|
- user has CREATE VIEW privilege on view table
|
|
|
|
- user has DROP privilege in case of ALTER VIEW or CREATE OR REPLACE
|
2004-10-07 14:43:04 +02:00
|
|
|
VIEW
|
2005-04-02 17:45:44 +02:00
|
|
|
- user has some (SELECT/UPDATE/INSERT/DELETE) privileges on columns of
|
2004-10-07 00:45:06 +02:00
|
|
|
underlying tables used on top of SELECT list (because it can be
|
|
|
|
(theoretically) updated, so it is enough to have UPDATE privilege on
|
|
|
|
them, for example)
|
2005-04-02 17:45:44 +02:00
|
|
|
- user has SELECT privilege on columns used in expressions of VIEW select
|
2004-10-07 00:45:06 +02:00
|
|
|
- for columns of underly tables used on top of SELECT list also will be
|
|
|
|
checked that we have not more privileges on correspondent column of view
|
|
|
|
table (i.e. user will not get some privileges by view creation)
|
|
|
|
*/
|
2004-10-07 14:43:04 +02:00
|
|
|
if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege,
|
2005-09-13 13:07:38 +02:00
|
|
|
0, 0, is_schema_db(view->db)) ||
|
2004-10-07 14:43:04 +02:00
|
|
|
grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) ||
|
|
|
|
(mode != VIEW_CREATE_NEW &&
|
2005-04-02 17:05:00 +02:00
|
|
|
(check_access(thd, DROP_ACL, view->db, &view->grant.privilege,
|
2005-09-13 13:07:38 +02:00
|
|
|
0, 0, is_schema_db(view->db)) ||
|
2005-04-02 17:05:00 +02:00
|
|
|
grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0))))
|
2005-08-17 21:42:53 +02:00
|
|
|
{
|
|
|
|
res= TRUE;
|
|
|
|
goto err;
|
|
|
|
}
|
2004-08-24 18:50:16 +02:00
|
|
|
for (sl= select_lex; sl; sl= sl->next_select())
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-08-24 18:50:16 +02:00
|
|
|
for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-08-24 18:50:16 +02:00
|
|
|
/*
|
2004-10-07 00:45:06 +02:00
|
|
|
Ensure that we have some privileges on this table, more strict check
|
2004-08-24 18:50:16 +02:00
|
|
|
will be done on column level after preparation,
|
|
|
|
*/
|
2004-09-03 21:38:45 +02:00
|
|
|
if (check_some_access(thd, VIEW_ANY_ACL, tbl))
|
2004-08-24 18:50:16 +02:00
|
|
|
{
|
now my_printf_error is not better then my_error, but my_error call is shorter
used only one implementation of format parser of (printf)
fixed multistatement
include/mysqld_error.h:
newerror messages
mysql-test/t/key.test:
unknown error replaced with real error
mysys/my_error.c:
my_error & my_printf_error use my_vsprintf
sql/field_conv.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/ha_innodb.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/handler.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_cmpfunc.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_func.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_strfunc.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/lock.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/log.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/parse_file.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/procedure.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/protocol.cc:
no need reset thd->lex->found_colon to break multiline sequance now, send_error called too late
sql/repl_failsafe.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/set_var.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/share/czech/errmsg.txt:
new errors converted from unknown error
sql/share/danish/errmsg.txt:
new errors converted from unknown error
sql/share/dutch/errmsg.txt:
new errors converted from unknown error
sql/share/english/errmsg.txt:
new errors converted from unknown error
sql/share/estonian/errmsg.txt:
new errors converted from unknown error
sql/share/french/errmsg.txt:
new errors converted from unknown error
sql/share/german/errmsg.txt:
new errors converted from unknown error
sql/share/greek/errmsg.txt:
new errors converted from unknown error
sql/share/hungarian/errmsg.txt:
new errors converted from unknown error
sql/share/italian/errmsg.txt:
new errors converted from unknown error
sql/share/japanese/errmsg.txt:
new errors converted from unknown error
sql/share/korean/errmsg.txt:
new errors converted from unknown error
sql/share/norwegian-ny/errmsg.txt:
new errors converted from unknown error
sql/share/norwegian/errmsg.txt:
new errors converted from unknown error
sql/share/polish/errmsg.txt:
new errors converted from unknown error
sql/share/portuguese/errmsg.txt:
new errors converted from unknown error
sql/share/romanian/errmsg.txt:
new errors converted from unknown error
sql/share/russian/errmsg.txt:
new errors converted from unknown error
sql/share/serbian/errmsg.txt:
new errors converted from unknown error
sql/share/slovak/errmsg.txt:
new errors converted from unknown error
sql/share/spanish/errmsg.txt:
new errors converted from unknown error
sql/share/swedish/errmsg.txt:
new errors converted from unknown error
sql/share/ukrainian/errmsg.txt:
new errors converted from unknown error
sql/slave.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sp.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sp_head.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_acl.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_analyse.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_base.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_class.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_db.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_delete.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_handler.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_insert.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_load.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_map.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_parse.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
multi-row command fixed
sql/sql_prepare.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
remover send_error ingected from 4.1
sql/sql_rename.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_repl.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_select.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_show.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_table.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_trigger.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_udf.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_update.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_view.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_yacc.yy:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/table.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
strings/my_vsnprintf.c:
* format support added to my_vsprint
2004-11-13 18:35:51 +01:00
|
|
|
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
|
2005-09-15 21:29:07 +02:00
|
|
|
"ANY", thd->security_ctx->priv_user,
|
|
|
|
thd->security_ctx->priv_host, tbl->table_name);
|
2005-08-17 21:42:53 +02:00
|
|
|
res= TRUE;
|
|
|
|
goto err;
|
2004-08-24 18:50:16 +02:00
|
|
|
}
|
2004-10-07 00:45:06 +02:00
|
|
|
/*
|
|
|
|
Mark this table as a table which will be checked after the prepare
|
|
|
|
phase
|
|
|
|
*/
|
2004-08-24 18:50:16 +02:00
|
|
|
tbl->table_in_first_from_clause= 1;
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2004-08-24 18:50:16 +02:00
|
|
|
/*
|
2004-10-07 00:45:06 +02:00
|
|
|
We need to check only SELECT_ACL for all normal fields, fields for
|
|
|
|
which we need "any" (SELECT/UPDATE/INSERT/DELETE) privilege will be
|
|
|
|
checked later
|
2004-08-24 18:50:16 +02:00
|
|
|
*/
|
|
|
|
tbl->grant.want_privilege= SELECT_ACL;
|
|
|
|
/*
|
2004-10-07 00:45:06 +02:00
|
|
|
Make sure that all rights are loaded to the TABLE::grant field.
|
2004-08-24 18:50:16 +02:00
|
|
|
|
2005-01-06 12:00:13 +01:00
|
|
|
tbl->table_name will be correct name of table because VIEWs are
|
2004-08-24 18:50:16 +02:00
|
|
|
not opened yet.
|
|
|
|
*/
|
|
|
|
fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
|
2005-01-06 12:00:13 +01:00
|
|
|
tbl->table_name);
|
2004-08-24 18:50:16 +02:00
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (&lex->select_lex != lex->all_selects_list)
|
|
|
|
{
|
|
|
|
/* check tables of subqueries */
|
2004-07-16 22:44:14 +02:00
|
|
|
for (tbl= tables; tbl; tbl= tbl->next_global)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
if (!tbl->table_in_first_from_clause)
|
|
|
|
{
|
|
|
|
if (check_access(thd, SELECT_ACL, tbl->db,
|
2005-09-13 13:07:38 +02:00
|
|
|
&tbl->grant.privilege, 0, 0, test(tbl->schema_table)) ||
|
2004-07-16 00:15:55 +02:00
|
|
|
grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0))
|
|
|
|
{
|
2004-10-20 03:04:37 +02:00
|
|
|
res= TRUE;
|
2004-07-16 00:15:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
2004-10-07 00:45:06 +02:00
|
|
|
Mark fields for special privilege check ("any" privilege)
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2004-08-24 18:50:16 +02:00
|
|
|
for (sl= select_lex; sl; sl= sl->next_select())
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-08-24 18:50:16 +02:00
|
|
|
List_iterator_fast<Item> it(sl->item_list);
|
2004-07-16 00:15:55 +02:00
|
|
|
Item *item;
|
|
|
|
while ((item= it++))
|
|
|
|
{
|
2004-09-16 22:45:20 +02:00
|
|
|
Item_field *field;
|
|
|
|
if ((field= item->filed_for_view_update()))
|
|
|
|
field->any_privileges= 1;
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
if (open_and_lock_tables(thd, tables))
|
2005-08-17 21:42:53 +02:00
|
|
|
{
|
|
|
|
res= TRUE;
|
|
|
|
goto err;
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2004-10-07 14:43:04 +02:00
|
|
|
/*
|
|
|
|
check that tables are not temporary and this VIEW do not used in query
|
2005-08-18 07:19:12 +02:00
|
|
|
(it is possible with ALTERing VIEW).
|
|
|
|
open_and_lock_tables can change the value of tables,
|
|
|
|
e.g. it may happen if before the function call tables was equal to 0.
|
|
|
|
*/
|
2005-08-22 00:13:37 +02:00
|
|
|
for (tbl= lex->query_tables; tbl; tbl= tbl->next_global)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-10-07 14:43:04 +02:00
|
|
|
/* is this table view and the same view which we creates now? */
|
|
|
|
if (tbl->view &&
|
|
|
|
strcmp(tbl->view_db.str, view->db) == 0 &&
|
2005-01-06 12:00:13 +01:00
|
|
|
strcmp(tbl->view_name.str, view->table_name) == 0)
|
2004-10-07 14:43:04 +02:00
|
|
|
{
|
|
|
|
my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str);
|
2004-10-20 03:04:37 +02:00
|
|
|
res= TRUE;
|
2004-10-07 14:43:04 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
2005-12-01 11:15:48 +01:00
|
|
|
tbl->table can be NULL when tbl is a placeholder for a view
|
|
|
|
that is indirectly referenced via a stored function from the
|
|
|
|
view being created. We don't check these indirectly
|
|
|
|
referenced views in CREATE VIEW so they don't have table
|
|
|
|
object.
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2005-12-01 11:15:48 +01:00
|
|
|
if (tbl->table)
|
|
|
|
{
|
|
|
|
/* is this table temporary and is not view? */
|
|
|
|
if (tbl->table->s->tmp_table != NO_TMP_TABLE && !tbl->view &&
|
|
|
|
!tbl->schema_table)
|
|
|
|
{
|
|
|
|
my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias);
|
|
|
|
res= TRUE;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
Copy the privileges of the underlying VIEWs which were filled by
|
|
|
|
fill_effective_table_privileges
|
|
|
|
(they were not copied at derived tables processing)
|
|
|
|
*/
|
|
|
|
tbl->table->grant.privilege= tbl->grant.privilege;
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
|
2004-10-07 00:45:06 +02:00
|
|
|
/* prepare select to resolve all fields */
|
2004-07-16 00:15:55 +02:00
|
|
|
lex->view_prepare_mode= 1;
|
A fix and a test case for Bug#6513 "Test Suite: Values inserted by using
cursor is interpreted latin1 character and Bug#9819 "Cursors: Mysql Server
Crash while fetching from table with 5 million records."
A fix for a possible memory leak when fetching into an SP cursor
in a long loop.
The patch uses a common implementation of cursors in the binary protocol and
in stored procedures and implements materialized cursors.
For implementation details, see comments in sql_cursor.cc
include/my_sys.h:
- declaration for multi_alloc_root
libmysqld/Makefile.am:
- drop protocol_cursor.cc, add sql_cursor.cc (replaces the old
implementation of cursors with a new one)
mysql-test/r/ctype_ujis.result:
- test results fixed (a test case for Bug#6513)
mysql-test/r/sp-big.result:
- test results fixed (a test case for Bug#9819)
mysql-test/t/ctype_ujis.test:
Add a test case for Bug#6513 "Test Suite: Values inserted by using cursor is
interpreted latin1 character"
mysql-test/t/sp-big.test:
Add a restricted test case for Bug#9819 "Cursors: Mysql Server Crash
while fetching from table with 5 million records."
mysys/my_alloc.c:
- an implementation of multi_alloc_root; this is largely a copy-paste
from mulalloc.c, but the function is small and there is no easy way
to reuse the existing C function.
sql/Makefile.am:
- add sql_cursor.h, sql_cursor.cc (a new implementation of stored procedure
cursors) and drop protocol_cursor.cc (the old one)
sql/handler.cc:
- now TABLE object has its mem_root always initialized.
Adjust the implementation handler::ha_open
sql/item_subselect.cc:
- adjust to the changed declaration of st_select_lex_unit::prepare
sql/protocol.h:
- drop Protocol_cursor
sql/sp_head.cc:
- move juggling with Query_arena::free_list and Item::next to
sp_eval_func_item, as this is needed in 3 places already.
sql/sp_head.h:
- declare a no-op implementation for cleanup_stmt in sp_instr_cpush.
This method is needed for non-materializing cursors, which are yet not
used in stored procedures.
- declaration for sp_eval_func_item
sql/sp_rcontext.cc:
- reimplement sp_cursor using the new implementation of server side cursors.
- use sp_eval_func_item to assign values of SP variables from the
row fetched from a cursor. This should fix a possible memory leak in
the old implementation of sp_cursor::fetch
sql/sp_rcontext.h:
- reimplement sp_cursor using the new implementation of server side cursors.
sql/sql_class.cc:
- disable the functionality that closes transient cursors at commit/rollback;
transient cursors are not used in 5.0, instead we use materialized ones.
To be enabled in a later version.
sql/sql_class.h:
- adjust to the rename Cursor -> Server_side_cursor
- additional declarations of select_union used in materialized cursors
sql/sql_derived.cc:
- reuse bits of tmp table code in UNION, derived tables, and materialized
cursors
- cleanup comments
sql/sql_lex.h:
- declarations of auxiliary methods used by materialized cursors
- a cleanup in st_select_lex_unit interface
sql/sql_list.h:
- add an array operator new[] to class Sql_alloc
sql/sql_prepare.cc:
- split the tight coupling of cursors and prepared statements to reuse
the same implementation in stored procedures
- cleanups of error processing in Prepared_statement::{prepare,execute}
sql/sql_select.cc:
- move the implementation of sensitive (non-materializing) cursors to
sql_cursor.cc
- make temporary tables self-contained: the table, its record and fields
are allocated in TABLE::mem_root. This implementation is not clean
and resets thd->mem_root several times because of the way create_tmp_table
works (many additional things are done inside it).
- adjust to the changed declaration of st_select_lex_unit::prepare
sql/sql_select.h:
- move the declaration of sensitive (non-materializing) cursors to
sql_cursor.cc
sql/sql_union.cc:
- move pieces of st_select_unit::prepare to select_union and st_table
methods to be able to reuse code in the implementation of materialized
cursors
sql/sql_view.cc:
- adjust to the changed signature of st_select_lex_unit::prepare
sql/table.cc:
- implement auxiliary st_table methods for use with temporary tables
sql/table.h:
- add declarations for auxiliary methods of st_table used to work with
temporary tables
tests/mysql_client_test.c:
- if cursors are materialized, a parallel update of the table used
in the cursor may go through: update the test.
sql/sql_cursor.cc:
New BitKeeper file ``sql/sql_cursor.cc'' -- implementation of server side
cursors
sql/sql_cursor.h:
New BitKeeper file ``sql/sql_cursor.h'' - declarations for
server side cursors.
2005-09-22 00:11:21 +02:00
|
|
|
if (unit->prepare(thd, 0, 0))
|
2004-08-23 11:38:55 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
some errors from prepare are reported to user, if is not then
|
|
|
|
it will be checked after err: label
|
|
|
|
*/
|
2004-10-20 03:04:37 +02:00
|
|
|
res= TRUE;
|
2004-07-16 00:15:55 +02:00
|
|
|
goto err;
|
2004-08-23 11:38:55 +02:00
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
/* view list (list of view fields names) */
|
|
|
|
if (lex->view_list.elements)
|
|
|
|
{
|
|
|
|
List_iterator_fast<Item> it(select_lex->item_list);
|
|
|
|
List_iterator_fast<LEX_STRING> nm(lex->view_list);
|
|
|
|
Item *item;
|
|
|
|
LEX_STRING *name;
|
2004-09-03 20:43:04 +02:00
|
|
|
|
|
|
|
if (lex->view_list.elements != select_lex->item_list.elements)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-03 20:43:04 +02:00
|
|
|
my_message(ER_VIEW_WRONG_LIST, ER(ER_VIEW_WRONG_LIST), MYF(0));
|
2005-09-14 09:53:09 +02:00
|
|
|
res= TRUE;
|
2004-09-03 20:43:04 +02:00
|
|
|
goto err;
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
2004-09-03 20:43:04 +02:00
|
|
|
while ((item= it++, name= nm++))
|
2005-06-21 19:30:48 +02:00
|
|
|
{
|
2004-09-03 20:43:04 +02:00
|
|
|
item->set_name(name->str, name->length, system_charset_info);
|
2005-06-21 19:30:48 +02:00
|
|
|
item->is_autogenerated_name= FALSE;
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
|
2005-08-10 15:45:00 +02:00
|
|
|
if (check_duplicate_names(select_lex->item_list, 1))
|
2005-08-17 21:42:53 +02:00
|
|
|
{
|
|
|
|
res= TRUE;
|
|
|
|
goto err;
|
|
|
|
}
|
2004-07-21 11:14:45 +02:00
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
|
|
/*
|
2004-10-07 00:45:06 +02:00
|
|
|
Compare/check grants on view with grants of underlying tables
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2004-08-24 18:50:16 +02:00
|
|
|
for (sl= select_lex; sl; sl= sl->next_select())
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
char *db= view->db ? view->db : thd->db;
|
2004-08-24 18:50:16 +02:00
|
|
|
List_iterator_fast<Item> it(sl->item_list);
|
2004-07-16 00:15:55 +02:00
|
|
|
Item *item;
|
|
|
|
fill_effective_table_privileges(thd, &view->grant, db,
|
2005-01-06 12:00:13 +01:00
|
|
|
view->table_name);
|
2004-09-03 20:43:04 +02:00
|
|
|
while ((item= it++))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-16 22:45:20 +02:00
|
|
|
Item_field *fld;
|
2004-07-16 00:15:55 +02:00
|
|
|
uint priv= (get_column_grant(thd, &view->grant, db,
|
2005-01-06 12:00:13 +01:00
|
|
|
view->table_name, item->name) &
|
2004-07-16 00:15:55 +02:00
|
|
|
VIEW_ANY_ACL);
|
2004-09-16 22:45:20 +02:00
|
|
|
if ((fld= item->filed_for_view_update()))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
/*
|
2004-10-07 00:45:06 +02:00
|
|
|
Do we have more privileges on view field then underlying table field?
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2005-01-06 12:00:13 +01:00
|
|
|
if (!fld->field->table->s->tmp_table && (~fld->have_privileges & priv))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
/* VIEW column has more privileges */
|
now my_printf_error is not better then my_error, but my_error call is shorter
used only one implementation of format parser of (printf)
fixed multistatement
include/mysqld_error.h:
newerror messages
mysql-test/t/key.test:
unknown error replaced with real error
mysys/my_error.c:
my_error & my_printf_error use my_vsprintf
sql/field_conv.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/ha_innodb.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/handler.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_cmpfunc.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_func.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_strfunc.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/lock.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/log.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/parse_file.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/procedure.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/protocol.cc:
no need reset thd->lex->found_colon to break multiline sequance now, send_error called too late
sql/repl_failsafe.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/set_var.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/share/czech/errmsg.txt:
new errors converted from unknown error
sql/share/danish/errmsg.txt:
new errors converted from unknown error
sql/share/dutch/errmsg.txt:
new errors converted from unknown error
sql/share/english/errmsg.txt:
new errors converted from unknown error
sql/share/estonian/errmsg.txt:
new errors converted from unknown error
sql/share/french/errmsg.txt:
new errors converted from unknown error
sql/share/german/errmsg.txt:
new errors converted from unknown error
sql/share/greek/errmsg.txt:
new errors converted from unknown error
sql/share/hungarian/errmsg.txt:
new errors converted from unknown error
sql/share/italian/errmsg.txt:
new errors converted from unknown error
sql/share/japanese/errmsg.txt:
new errors converted from unknown error
sql/share/korean/errmsg.txt:
new errors converted from unknown error
sql/share/norwegian-ny/errmsg.txt:
new errors converted from unknown error
sql/share/norwegian/errmsg.txt:
new errors converted from unknown error
sql/share/polish/errmsg.txt:
new errors converted from unknown error
sql/share/portuguese/errmsg.txt:
new errors converted from unknown error
sql/share/romanian/errmsg.txt:
new errors converted from unknown error
sql/share/russian/errmsg.txt:
new errors converted from unknown error
sql/share/serbian/errmsg.txt:
new errors converted from unknown error
sql/share/slovak/errmsg.txt:
new errors converted from unknown error
sql/share/spanish/errmsg.txt:
new errors converted from unknown error
sql/share/swedish/errmsg.txt:
new errors converted from unknown error
sql/share/ukrainian/errmsg.txt:
new errors converted from unknown error
sql/slave.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sp.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sp_head.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_acl.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_analyse.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_base.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_class.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_db.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_delete.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_handler.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_insert.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_load.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_map.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_parse.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
multi-row command fixed
sql/sql_prepare.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
remover send_error ingected from 4.1
sql/sql_rename.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_repl.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_select.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_show.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_table.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_trigger.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_udf.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_update.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_view.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_yacc.yy:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/table.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
strings/my_vsnprintf.c:
* format support added to my_vsprint
2004-11-13 18:35:51 +01:00
|
|
|
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
2005-09-15 21:29:07 +02:00
|
|
|
"create view", thd->security_ctx->priv_user,
|
|
|
|
thd->security_ctx->priv_host, item->name,
|
2005-01-06 12:00:13 +01:00
|
|
|
view->table_name);
|
2005-08-17 21:42:53 +02:00
|
|
|
res= TRUE;
|
|
|
|
goto err;
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-09-09 05:59:26 +02:00
|
|
|
if (wait_if_global_read_lock(thd, 0, 0))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-10-20 03:04:37 +02:00
|
|
|
res= TRUE;
|
2004-07-16 00:15:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
VOID(pthread_mutex_lock(&LOCK_open));
|
2004-09-03 20:43:04 +02:00
|
|
|
res= mysql_register_view(thd, view, mode);
|
2004-07-16 00:15:55 +02:00
|
|
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
2005-01-27 13:21:37 +01:00
|
|
|
if (view->revision != 1)
|
|
|
|
query_cache_invalidate3(thd, view, 0);
|
2004-07-16 00:15:55 +02:00
|
|
|
start_waiting_global_read_lock(thd);
|
2004-09-03 20:43:04 +02:00
|
|
|
if (res)
|
|
|
|
goto err;
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
send_ok(thd);
|
|
|
|
lex->link_first_table_back(view, link_to_local);
|
2004-12-06 16:15:54 +01:00
|
|
|
DBUG_RETURN(0);
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
err:
|
|
|
|
thd->proc_info= "end";
|
|
|
|
lex->link_first_table_back(view, link_to_local);
|
|
|
|
unit->cleanup();
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(res || thd->net.report_error);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-09-01 21:48:59 +02:00
|
|
|
/* index of revision number in following table */
|
2005-09-14 09:53:09 +02:00
|
|
|
static const int revision_number_position= 8;
|
2004-09-01 21:48:59 +02:00
|
|
|
/* index of last required parameter for making view */
|
2005-09-14 09:53:09 +02:00
|
|
|
static const int required_view_parameters= 10;
|
2005-09-16 17:13:21 +02:00
|
|
|
/* number of backups */
|
|
|
|
static const int num_view_backups= 3;
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2004-09-03 20:43:04 +02:00
|
|
|
/*
|
|
|
|
table of VIEW .frm field descriptors
|
|
|
|
|
|
|
|
Note that one should NOT change the order for this, as it's used by
|
|
|
|
parse()
|
|
|
|
*/
|
2004-07-16 00:15:55 +02:00
|
|
|
static File_option view_parameters[]=
|
2005-09-14 09:53:09 +02:00
|
|
|
{{{(char*) STRING_WITH_LEN("query")},
|
|
|
|
offsetof(TABLE_LIST, query),
|
2005-11-11 18:03:32 +01:00
|
|
|
FILE_OPTIONS_ESTRING},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*) STRING_WITH_LEN("md5")},
|
|
|
|
offsetof(TABLE_LIST, md5),
|
|
|
|
FILE_OPTIONS_STRING},
|
|
|
|
{{(char*) STRING_WITH_LEN("updatable")},
|
|
|
|
offsetof(TABLE_LIST, updatable_view),
|
|
|
|
FILE_OPTIONS_ULONGLONG},
|
|
|
|
{{(char*) STRING_WITH_LEN("algorithm")},
|
|
|
|
offsetof(TABLE_LIST, algorithm),
|
|
|
|
FILE_OPTIONS_ULONGLONG},
|
|
|
|
{{(char*) STRING_WITH_LEN("definer_user")},
|
|
|
|
offsetof(TABLE_LIST, definer.user),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_STRING},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*) STRING_WITH_LEN("definer_host")},
|
|
|
|
offsetof(TABLE_LIST, definer.host),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_STRING},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*) STRING_WITH_LEN("suid")},
|
|
|
|
offsetof(TABLE_LIST, view_suid),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_ULONGLONG},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*) STRING_WITH_LEN("with_check_option")},
|
|
|
|
offsetof(TABLE_LIST, with_check),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_ULONGLONG},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*) STRING_WITH_LEN("revision")},
|
|
|
|
offsetof(TABLE_LIST, revision),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_REV},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*) STRING_WITH_LEN("timestamp")},
|
|
|
|
offsetof(TABLE_LIST, timestamp),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_TIMESTAMP},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*)STRING_WITH_LEN("create-version")},
|
|
|
|
offsetof(TABLE_LIST, file_version),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_ULONGLONG},
|
2005-09-14 09:53:09 +02:00
|
|
|
{{(char*) STRING_WITH_LEN("source")},
|
|
|
|
offsetof(TABLE_LIST, source),
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_ESTRING},
|
2004-11-03 11:39:38 +01:00
|
|
|
{{NullS, 0}, 0,
|
2004-07-16 00:15:55 +02:00
|
|
|
FILE_OPTIONS_STRING}
|
|
|
|
};
|
|
|
|
|
2005-07-31 11:49:55 +02:00
|
|
|
static LEX_STRING view_file_type[]= {{(char*) STRING_WITH_LEN("VIEW") }};
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Register VIEW (write .frm & process .frm's history backups)
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mysql_register_view()
|
|
|
|
thd - thread handler
|
|
|
|
view - view description
|
|
|
|
mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 OK
|
|
|
|
-1 Error
|
|
|
|
1 Error and error message given
|
|
|
|
*/
|
2004-09-11 22:52:55 +02:00
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|
|
|
enum_view_create_mode mode)
|
|
|
|
{
|
2004-10-25 16:32:28 +02:00
|
|
|
LEX *lex= thd->lex;
|
2004-07-16 00:15:55 +02:00
|
|
|
char buff[4096];
|
|
|
|
String str(buff,(uint32) sizeof(buff), system_charset_info);
|
2004-10-28 18:37:25 +02:00
|
|
|
char md5[MD5_BUFF_LENGTH];
|
2004-07-16 00:15:55 +02:00
|
|
|
bool can_be_merged;
|
2005-12-31 06:01:26 +01:00
|
|
|
char dir_buff[FN_REFLEN], file_buff[FN_REFLEN], path_buff[FN_REFLEN];
|
|
|
|
LEX_STRING dir, file, path;
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_ENTER("mysql_register_view");
|
|
|
|
|
2004-10-07 00:45:06 +02:00
|
|
|
/* print query */
|
2004-07-16 00:15:55 +02:00
|
|
|
str.length(0);
|
2004-07-20 17:51:02 +02:00
|
|
|
{
|
|
|
|
ulong sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
|
|
|
|
thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
|
2004-10-25 16:32:28 +02:00
|
|
|
lex->unit.print(&str);
|
2004-07-20 17:51:02 +02:00
|
|
|
thd->variables.sql_mode|= sql_mode;
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
str.append('\0');
|
2005-07-31 11:49:55 +02:00
|
|
|
DBUG_PRINT("info", ("View: %s", str.ptr()));
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2004-10-07 00:45:06 +02:00
|
|
|
/* print file name */
|
2005-12-31 06:01:26 +01:00
|
|
|
dir.length= build_table_filename(dir_buff, sizeof(dir_buff),
|
|
|
|
view->db, "", "");
|
2004-07-16 00:15:55 +02:00
|
|
|
dir.str= dir_buff;
|
|
|
|
|
2005-12-31 06:01:26 +01:00
|
|
|
path.length= build_table_filename(path_buff, sizeof(path_buff),
|
|
|
|
view->db, view->table_name, reg_ext);
|
|
|
|
path.str= path_buff;
|
|
|
|
|
|
|
|
file.str= path.str + dir.length;
|
|
|
|
file.length= path.length - dir.length;
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/* init timestamp */
|
2004-09-03 20:43:04 +02:00
|
|
|
if (!view->timestamp.str)
|
2004-07-16 00:15:55 +02:00
|
|
|
view->timestamp.str= view->timestamp_buffer;
|
|
|
|
|
2004-10-07 00:45:06 +02:00
|
|
|
/* check old .frm */
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
char path_buff[FN_REFLEN];
|
|
|
|
LEX_STRING path;
|
2004-09-03 20:43:04 +02:00
|
|
|
File_parser *parser;
|
2004-09-29 15:35:01 +02:00
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
path.str= path_buff;
|
|
|
|
fn_format(path_buff, file.str, dir.str, 0, MY_UNPACK_FILENAME);
|
|
|
|
path.length= strlen(path_buff);
|
|
|
|
|
|
|
|
if (!access(path.str, F_OK))
|
|
|
|
{
|
|
|
|
if (mode == VIEW_CREATE_NEW)
|
|
|
|
{
|
|
|
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
|
2004-09-03 14:18:40 +02:00
|
|
|
DBUG_RETURN(-1);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
|
2004-11-09 02:58:44 +01:00
|
|
|
if (!(parser= sql_parse_prepare(&path, thd->mem_root, 0)))
|
2004-09-03 20:43:04 +02:00
|
|
|
DBUG_RETURN(1);
|
|
|
|
|
2005-07-31 11:49:55 +02:00
|
|
|
if (!parser->ok() || !is_equal(&view_type, parser->type()))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
now my_printf_error is not better then my_error, but my_error call is shorter
used only one implementation of format parser of (printf)
fixed multistatement
include/mysqld_error.h:
newerror messages
mysql-test/t/key.test:
unknown error replaced with real error
mysys/my_error.c:
my_error & my_printf_error use my_vsprintf
sql/field_conv.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/ha_innodb.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/handler.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_cmpfunc.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_func.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/item_strfunc.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/lock.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/log.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/parse_file.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/procedure.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/protocol.cc:
no need reset thd->lex->found_colon to break multiline sequance now, send_error called too late
sql/repl_failsafe.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/set_var.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/share/czech/errmsg.txt:
new errors converted from unknown error
sql/share/danish/errmsg.txt:
new errors converted from unknown error
sql/share/dutch/errmsg.txt:
new errors converted from unknown error
sql/share/english/errmsg.txt:
new errors converted from unknown error
sql/share/estonian/errmsg.txt:
new errors converted from unknown error
sql/share/french/errmsg.txt:
new errors converted from unknown error
sql/share/german/errmsg.txt:
new errors converted from unknown error
sql/share/greek/errmsg.txt:
new errors converted from unknown error
sql/share/hungarian/errmsg.txt:
new errors converted from unknown error
sql/share/italian/errmsg.txt:
new errors converted from unknown error
sql/share/japanese/errmsg.txt:
new errors converted from unknown error
sql/share/korean/errmsg.txt:
new errors converted from unknown error
sql/share/norwegian-ny/errmsg.txt:
new errors converted from unknown error
sql/share/norwegian/errmsg.txt:
new errors converted from unknown error
sql/share/polish/errmsg.txt:
new errors converted from unknown error
sql/share/portuguese/errmsg.txt:
new errors converted from unknown error
sql/share/romanian/errmsg.txt:
new errors converted from unknown error
sql/share/russian/errmsg.txt:
new errors converted from unknown error
sql/share/serbian/errmsg.txt:
new errors converted from unknown error
sql/share/slovak/errmsg.txt:
new errors converted from unknown error
sql/share/spanish/errmsg.txt:
new errors converted from unknown error
sql/share/swedish/errmsg.txt:
new errors converted from unknown error
sql/share/ukrainian/errmsg.txt:
new errors converted from unknown error
sql/slave.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sp.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sp_head.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_acl.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_analyse.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_base.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_class.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_db.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_delete.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_handler.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_insert.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_load.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_map.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_parse.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
multi-row command fixed
sql/sql_prepare.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
remover send_error ingected from 4.1
sql/sql_rename.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_repl.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_select.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_show.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_table.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_trigger.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_udf.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_update.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_view.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/sql_yacc.yy:
now my_printf_error is not better then my_error, but my_error call is shorter
sql/table.cc:
now my_printf_error is not better then my_error, but my_error call is shorter
strings/my_vsnprintf.c:
* format support added to my_vsprint
2004-11-13 18:35:51 +01:00
|
|
|
my_error(ER_WRONG_OBJECT, MYF(0),
|
2005-01-06 12:00:13 +01:00
|
|
|
(view->db ? view->db : thd->db), view->table_name, "VIEW");
|
2004-09-05 21:14:27 +02:00
|
|
|
DBUG_RETURN(-1);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
2004-09-03 20:43:04 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
read revision number
|
2004-09-11 22:52:55 +02:00
|
|
|
|
2004-10-07 00:45:06 +02:00
|
|
|
TODO: read dependence list, too, to process cascade/restrict
|
2004-09-03 20:43:04 +02:00
|
|
|
TODO: special cascade/restrict procedure for alter?
|
|
|
|
*/
|
2004-11-09 02:58:44 +01:00
|
|
|
if (parser->parse((gptr)view, thd->mem_root,
|
2005-11-20 19:47:07 +01:00
|
|
|
view_parameters + revision_number_position, 1,
|
|
|
|
&file_parser_dummy_hook))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-05 21:14:27 +02:00
|
|
|
DBUG_RETURN(thd->net.report_error? -1 : 0);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (mode == VIEW_ALTER)
|
|
|
|
{
|
|
|
|
my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias);
|
2004-09-03 14:18:40 +02:00
|
|
|
DBUG_RETURN(-1);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-10-07 00:45:06 +02:00
|
|
|
/* fill structure */
|
2004-07-16 00:15:55 +02:00
|
|
|
view->query.str= (char*)str.ptr();
|
|
|
|
view->query.length= str.length()-1; // we do not need last \0
|
2005-12-02 20:18:12 +01:00
|
|
|
view->source.str= thd->query + thd->lex->create_view_select_start;
|
2005-09-14 09:53:09 +02:00
|
|
|
view->source.length= (thd->query_length -
|
2005-12-02 20:18:12 +01:00
|
|
|
thd->lex->create_view_select_start);
|
2004-07-16 00:15:55 +02:00
|
|
|
view->file_version= 1;
|
|
|
|
view->calc_md5(md5);
|
|
|
|
view->md5.str= md5;
|
|
|
|
view->md5.length= 32;
|
2004-10-25 16:32:28 +02:00
|
|
|
can_be_merged= lex->can_be_merged();
|
|
|
|
if (lex->create_view_algorithm == VIEW_ALGORITHM_MERGE &&
|
|
|
|
!lex->can_be_merged())
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
|
|
|
|
ER(ER_WARN_VIEW_MERGE));
|
2004-10-25 16:32:28 +02:00
|
|
|
lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
2004-10-25 16:32:28 +02:00
|
|
|
view->algorithm= lex->create_view_algorithm;
|
2005-11-10 20:25:03 +01:00
|
|
|
view->definer.user= lex->definer->user;
|
|
|
|
view->definer.host= lex->definer->host;
|
2005-09-14 09:53:09 +02:00
|
|
|
view->view_suid= lex->create_view_suid;
|
2004-10-25 16:32:28 +02:00
|
|
|
view->with_check= lex->create_view_check;
|
2004-07-22 16:52:04 +02:00
|
|
|
if ((view->updatable_view= (can_be_merged &&
|
2004-09-03 21:38:45 +02:00
|
|
|
view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-10-07 00:45:06 +02:00
|
|
|
/* TODO: change here when we will support UNIONs */
|
2004-10-25 16:32:28 +02:00
|
|
|
for (TABLE_LIST *tbl= (TABLE_LIST *)lex->select_lex.table_list.first;
|
2004-09-15 22:42:56 +02:00
|
|
|
tbl;
|
|
|
|
tbl= tbl->next_local)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-11-13 11:56:39 +01:00
|
|
|
if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
|
post-merge fix
mysql-test/r/view.result:
changes in error number, and key in view processing
mysql-test/t/view.test:
changes in error number, and key in view processing
sql/mysql_priv.h:
changes functions
sql/sp.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_base.cc:
fixed finding table, taking in account join view, which can have not TABLE pointer
now we report to setup_tables(), are we setuping SELECT...INSERT and ennumerete insert table separately
sql/sql_delete.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_help.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_insert.cc:
fixed returning value of functions
sql/sql_load.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
removed second setup_tables call (merge)
sql/sql_olap.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_parse.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_prepare.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_select.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_update.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_view.cc:
returning value fixed
sql/sql_view.h:
returning value fixed
2004-11-25 01:23:13 +01:00
|
|
|
{
|
2004-09-15 22:42:56 +02:00
|
|
|
view->updatable_view= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
for (TABLE_LIST *up= tbl; up; up= up->embedding)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-15 22:42:56 +02:00
|
|
|
if (up->outer_join)
|
|
|
|
{
|
|
|
|
view->updatable_view= 0;
|
|
|
|
goto loop_out;
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-09-15 22:42:56 +02:00
|
|
|
loop_out:
|
2004-10-25 16:32:28 +02:00
|
|
|
/*
|
|
|
|
Check that table of main select do not used in subqueries.
|
|
|
|
|
|
|
|
This test can catch only very simple cases of such non-updateable views,
|
|
|
|
all other will be detected before updating commands execution.
|
|
|
|
(it is more optimisation then real check)
|
|
|
|
|
|
|
|
NOTE: this skip cases of using table via VIEWs, joined VIEWs, VIEWs with
|
|
|
|
UNION
|
|
|
|
*/
|
|
|
|
if (view->updatable_view &&
|
|
|
|
!lex->select_lex.next_select() &&
|
|
|
|
!((TABLE_LIST*)lex->select_lex.table_list.first)->next_local &&
|
|
|
|
find_table_in_global_list(lex->query_tables->next_global,
|
|
|
|
lex->query_tables->db,
|
2005-01-06 12:00:13 +01:00
|
|
|
lex->query_tables->table_name))
|
2004-10-25 16:32:28 +02:00
|
|
|
{
|
|
|
|
view->updatable_view= 0;
|
|
|
|
}
|
|
|
|
|
2004-09-03 14:18:40 +02:00
|
|
|
if (view->with_check != VIEW_CHECK_NONE &&
|
|
|
|
!view->updatable_view)
|
|
|
|
{
|
2005-01-06 12:00:13 +01:00
|
|
|
my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->table_name);
|
2004-09-03 14:18:40 +02:00
|
|
|
DBUG_RETURN(-1);
|
|
|
|
}
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
if (sql_create_definition_file(&dir, &file, view_file_type,
|
2005-09-16 17:13:21 +02:00
|
|
|
(gptr)view, view_parameters, num_view_backups))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-03 14:18:40 +02:00
|
|
|
DBUG_RETURN(thd->net.report_error? -1 : 1);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-27 23:18:23 +02:00
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
|
|
|
read VIEW .frm and create structures
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mysql_make_view()
|
2005-11-01 14:54:30 +01:00
|
|
|
thd Thread handler
|
|
|
|
parser parser object
|
|
|
|
table TABLE_LIST structure for filling
|
2004-07-21 03:26:20 +02:00
|
|
|
|
|
|
|
RETURN
|
2004-09-03 20:43:04 +02:00
|
|
|
0 ok
|
|
|
|
1 error
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2004-09-03 20:43:04 +02:00
|
|
|
|
2005-11-01 14:54:30 +01:00
|
|
|
bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2005-11-01 14:54:30 +01:00
|
|
|
SELECT_LEX *end, *view_select;
|
|
|
|
LEX *old_lex, *lex;
|
|
|
|
Query_arena *arena, backup;
|
2006-04-13 22:12:26 +02:00
|
|
|
TABLE_LIST *top_view= table->top_table();
|
2005-11-01 14:54:30 +01:00
|
|
|
int res;
|
|
|
|
bool result;
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_ENTER("mysql_make_view");
|
2005-11-01 14:54:30 +01:00
|
|
|
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
if (table->view)
|
|
|
|
{
|
2005-10-27 23:18:23 +02:00
|
|
|
/*
|
|
|
|
It's an execution of a PS/SP and the view has already been unfolded
|
|
|
|
into a list of used tables. Now we only need to update the information
|
|
|
|
about granted privileges in the view tables with the actual data
|
|
|
|
stored in MySQL privilege system. We don't need to restore the
|
|
|
|
required privileges (by calling register_want_access) because they has
|
|
|
|
not changed since PREPARE or the previous execution: the only case
|
|
|
|
when this information is changed is execution of UPDATE on a view, but
|
|
|
|
the original want_access is restored in its end.
|
|
|
|
*/
|
|
|
|
if (!table->prelocking_placeholder && table->prepare_security(thd))
|
|
|
|
{
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_PRINT("info",
|
2004-09-03 20:43:04 +02:00
|
|
|
("VIEW %s.%s is already processed on previous PS/SP execution",
|
2004-07-16 00:15:55 +02:00
|
|
|
table->view_db.str, table->view_name.str));
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
2006-04-13 22:12:26 +02:00
|
|
|
/* check loop via view definition */
|
|
|
|
for (TABLE_LIST *precedent= table->referencing_view;
|
|
|
|
precedent;
|
|
|
|
precedent= precedent->referencing_view)
|
|
|
|
{
|
|
|
|
if (precedent->view_name.length == table->table_name_length &&
|
|
|
|
precedent->view_db.length == table->db_length &&
|
|
|
|
my_strcasecmp(system_charset_info,
|
|
|
|
precedent->view_name.str, table->table_name) == 0 &&
|
|
|
|
my_strcasecmp(system_charset_info,
|
|
|
|
precedent->view_db.str, table->db) == 0)
|
|
|
|
{
|
|
|
|
my_error(ER_VIEW_RECURSIVE, MYF(0),
|
|
|
|
top_view->view_db.str, top_view->view_name.str);
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
|
|
|
For now we assume that tables will not be changed during PS life (it
|
|
|
|
will be TRUE as far as we make new table cache).
|
|
|
|
*/
|
2005-11-01 14:54:30 +01:00
|
|
|
old_lex= thd->lex;
|
|
|
|
arena= thd->stmt_arena;
|
2004-09-10 01:22:44 +02:00
|
|
|
if (arena->is_conventional())
|
2004-09-09 05:59:26 +02:00
|
|
|
arena= 0;
|
|
|
|
else
|
2005-09-02 15:21:19 +02:00
|
|
|
thd->set_n_backup_active_arena(arena, &backup);
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
/* init timestamp */
|
2004-09-03 20:43:04 +02:00
|
|
|
if (!table->timestamp.str)
|
2004-07-16 00:15:55 +02:00
|
|
|
table->timestamp.str= table->timestamp_buffer;
|
2005-09-14 09:53:09 +02:00
|
|
|
/* prepare default values for old format */
|
2005-10-27 23:18:23 +02:00
|
|
|
table->view_suid= TRUE;
|
2005-09-14 09:53:09 +02:00
|
|
|
table->definer.user.str= table->definer.host.str= 0;
|
|
|
|
table->definer.user.length= table->definer.host.length= 0;
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
|
|
|
TODO: when VIEWs will be stored in cache, table mem_root should
|
|
|
|
be used here
|
|
|
|
*/
|
2004-11-09 02:58:44 +01:00
|
|
|
if (parser->parse((gptr)table, thd->mem_root, view_parameters,
|
2005-11-20 19:47:07 +01:00
|
|
|
required_view_parameters, &file_parser_dummy_hook))
|
2004-07-16 00:15:55 +02:00
|
|
|
goto err;
|
|
|
|
|
2005-09-14 09:53:09 +02:00
|
|
|
/*
|
|
|
|
check old format view .frm
|
|
|
|
*/
|
|
|
|
if (!table->definer.user.str)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(!table->definer.host.str &&
|
|
|
|
!table->definer.user.length &&
|
|
|
|
!table->definer.host.length);
|
|
|
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
|
|
|
|
table->db, table->table_name);
|
2006-03-02 12:17:13 +01:00
|
|
|
get_default_definer(thd, &table->definer);
|
2005-09-14 09:53:09 +02:00
|
|
|
}
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
|
|
|
Save VIEW parameters, which will be wiped out by derived table
|
|
|
|
processing
|
|
|
|
*/
|
|
|
|
table->view_db.str= table->db;
|
|
|
|
table->view_db.length= table->db_length;
|
2005-01-06 12:00:13 +01:00
|
|
|
table->view_name.str= table->table_name;
|
|
|
|
table->view_name.length= table->table_name_length;
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2004-07-16 14:20:51 +02:00
|
|
|
/*TODO: md5 test here and warning if it is differ */
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2004-07-16 14:20:51 +02:00
|
|
|
/*
|
|
|
|
TODO: TABLE mem root should be used here when VIEW will be stored in
|
|
|
|
TABLE cache
|
|
|
|
|
|
|
|
now Lex placed in statement memory
|
|
|
|
*/
|
2004-11-09 02:58:44 +01:00
|
|
|
table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local;
|
2004-11-03 11:39:38 +01:00
|
|
|
lex_start(thd, (uchar*)table->query.str, table->query.length);
|
2004-09-14 18:28:29 +02:00
|
|
|
view_select= &lex->select_lex;
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
view_select->select_number= ++thd->select_number;
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2005-07-28 21:39:11 +02:00
|
|
|
ulong save_mode= thd->variables.sql_mode;
|
2004-07-16 00:15:55 +02:00
|
|
|
/* 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
|
|
|
|
+ MODE_ANSI_QUOTES affect expression parsing
|
|
|
|
+ MODE_IGNORE_SPACE affect expression parsing
|
|
|
|
- MODE_NOT_USED not used :)
|
|
|
|
* MODE_ONLY_FULL_GROUP_BY affect execution
|
|
|
|
* MODE_NO_UNSIGNED_SUBTRACTION affect execution
|
|
|
|
- MODE_NO_DIR_IN_CREATE affect table creation only
|
|
|
|
- MODE_POSTGRESQL compounded from other modes
|
|
|
|
- MODE_ORACLE compounded from other modes
|
|
|
|
- MODE_MSSQL compounded from other modes
|
|
|
|
- MODE_DB2 compounded from other modes
|
|
|
|
- MODE_MAXDB affect only CREATE TABLE parsing
|
|
|
|
- MODE_NO_KEY_OPTIONS affect only SHOW
|
|
|
|
- MODE_NO_TABLE_OPTIONS affect only SHOW
|
|
|
|
- MODE_NO_FIELD_OPTIONS affect only SHOW
|
|
|
|
- MODE_MYSQL323 affect only SHOW
|
|
|
|
- MODE_MYSQL40 affect only SHOW
|
|
|
|
- MODE_ANSI compounded from other modes
|
|
|
|
(+ transaction mode)
|
|
|
|
? MODE_NO_AUTO_VALUE_ON_ZERO affect UPDATEs
|
|
|
|
+ MODE_NO_BACKSLASH_ESCAPES affect expression parsing
|
|
|
|
*/
|
2005-07-28 21:39:11 +02:00
|
|
|
thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
|
|
|
|
MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES);
|
2004-09-01 21:48:59 +02:00
|
|
|
CHARSET_INFO *save_cs= thd->variables.character_set_client;
|
2004-09-03 20:38:01 +02:00
|
|
|
thd->variables.character_set_client= system_charset_info;
|
2006-03-10 01:44:08 +01:00
|
|
|
res= MYSQLparse((void *)thd);
|
2004-09-01 21:48:59 +02:00
|
|
|
thd->variables.character_set_client= save_cs;
|
2005-07-28 21:39:11 +02:00
|
|
|
thd->variables.sql_mode= save_mode;
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
if (!res && !thd->is_fatal_error)
|
|
|
|
{
|
2004-09-11 22:52:55 +02:00
|
|
|
TABLE_LIST *view_tables= lex->query_tables;
|
|
|
|
TABLE_LIST *view_tables_tail= 0;
|
2004-09-14 18:28:29 +02:00
|
|
|
TABLE_LIST *tbl;
|
2004-07-16 14:20:51 +02:00
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
Check rights to run commands (EXPLAIN SELECT & SHOW CREATE) which show
|
|
|
|
underlying tables.
|
|
|
|
Skip this step if we are opening view for prelocking only.
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
if (!table->prelocking_placeholder &&
|
|
|
|
(old_lex->sql_command == SQLCOM_SELECT && old_lex->describe))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-11 22:52:55 +02:00
|
|
|
if (check_table_access(thd, SELECT_ACL, view_tables, 1) &&
|
2004-09-17 21:23:59 +02:00
|
|
|
check_table_access(thd, SHOW_VIEW_ACL, table, 1))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-11-12 13:34:00 +01:00
|
|
|
my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
|
2004-07-16 00:15:55 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
else if (!table->prelocking_placeholder &&
|
|
|
|
old_lex->sql_command == SQLCOM_SHOW_CREATE)
|
2004-09-17 21:23:59 +02:00
|
|
|
{
|
|
|
|
if (check_table_access(thd, SHOW_VIEW_ACL, table, 0))
|
|
|
|
goto err;
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2005-10-27 23:18:23 +02:00
|
|
|
if (!(table->view_tables=
|
|
|
|
(List<TABLE_LIST>*) new(thd->mem_root) List<TABLE_LIST>))
|
|
|
|
goto err;
|
2005-01-04 17:04:16 +01:00
|
|
|
/*
|
|
|
|
mark to avoid temporary table using and put view reference and find
|
|
|
|
last view table
|
|
|
|
*/
|
|
|
|
for (tbl= view_tables;
|
|
|
|
tbl;
|
|
|
|
tbl= (view_tables_tail= tbl)->next_global)
|
|
|
|
{
|
|
|
|
tbl->skip_temporary= 1;
|
|
|
|
tbl->belong_to_view= top_view;
|
2005-10-27 23:18:23 +02:00
|
|
|
tbl->referencing_view= table;
|
2006-03-28 13:06:29 +02:00
|
|
|
tbl->prelocking_placeholder= table->prelocking_placeholder;
|
2005-10-27 23:18:23 +02:00
|
|
|
/*
|
|
|
|
First we fill want_privilege with SELECT_ACL (this is needed for the
|
|
|
|
tables which belongs to view subqueries and temporary table views,
|
|
|
|
then for the merged view underlying tables we will set wanted
|
|
|
|
privileges of top_view
|
|
|
|
*/
|
|
|
|
tbl->grant.want_privilege= SELECT_ACL;
|
|
|
|
/*
|
|
|
|
After unfolding the view we lose the list of tables referenced in it
|
|
|
|
(we will have only a list of underlying tables in case of MERGE
|
|
|
|
algorithm, which does not include the tables referenced from
|
|
|
|
subqueries used in view definition).
|
|
|
|
Let's build a list of all tables referenced in the view.
|
|
|
|
*/
|
|
|
|
table->view_tables->push_back(tbl);
|
2005-01-04 17:04:16 +01:00
|
|
|
}
|
|
|
|
|
2004-09-11 22:52:55 +02:00
|
|
|
/*
|
|
|
|
Put tables of VIEW after VIEW TABLE_LIST
|
|
|
|
|
|
|
|
NOTE: It is important for UPDATE/INSERT/DELETE checks to have this
|
|
|
|
tables just after VIEW instead of tail of list, to be able check that
|
|
|
|
table is unique. Also we store old next table for the same purpose.
|
|
|
|
*/
|
|
|
|
if (view_tables)
|
|
|
|
{
|
|
|
|
if (table->next_global)
|
|
|
|
{
|
2004-10-25 16:32:28 +02:00
|
|
|
view_tables_tail->next_global= table->next_global;
|
2004-09-11 22:52:55 +02:00
|
|
|
table->next_global->prev_global= &view_tables_tail->next_global;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
old_lex->query_tables_last= &view_tables_tail->next_global;
|
2004-09-11 22:52:55 +02:00
|
|
|
}
|
|
|
|
view_tables->prev_global= &table->next_global;
|
|
|
|
table->next_global= view_tables;
|
|
|
|
}
|
|
|
|
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
/*
|
|
|
|
If we are opening this view as part of implicit LOCK TABLES, then
|
|
|
|
this view serves as simple placeholder and we should not continue
|
|
|
|
further processing.
|
|
|
|
*/
|
|
|
|
if (table->prelocking_placeholder)
|
|
|
|
goto ok2;
|
|
|
|
|
2005-10-27 23:18:23 +02:00
|
|
|
old_lex->derived_tables|= (DERIVED_VIEW | lex->derived_tables);
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
|
|
|
|
/* move SQL_NO_CACHE & Co to whole query */
|
|
|
|
old_lex->safe_to_cache_query= (old_lex->safe_to_cache_query &&
|
|
|
|
lex->safe_to_cache_query);
|
|
|
|
/* move SQL_CACHE to whole query */
|
|
|
|
if (view_select->options & OPTION_TO_QUERY_CACHE)
|
|
|
|
old_lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
|
|
|
|
|
2005-10-27 23:18:23 +02:00
|
|
|
if (table->view_suid)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Prepare a security context to check underlying objects of the view
|
|
|
|
*/
|
|
|
|
Security_context *save_security_ctx= thd->security_ctx;
|
|
|
|
if (!(table->view_sctx= (Security_context *)
|
|
|
|
thd->stmt_arena->alloc(sizeof(Security_context))))
|
|
|
|
goto err;
|
|
|
|
/* Assign the context to the tables referenced in the view */
|
|
|
|
for (tbl= view_tables; tbl; tbl= tbl->next_global)
|
|
|
|
tbl->security_ctx= table->view_sctx;
|
|
|
|
/* assign security context to SELECT name resolution contexts of view */
|
|
|
|
for(SELECT_LEX *sl= lex->all_selects_list;
|
|
|
|
sl;
|
|
|
|
sl= sl->next_select_in_list())
|
|
|
|
sl->context.security_ctx= table->view_sctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Setup an error processor to hide error messages issued by stored
|
|
|
|
routines referenced in the view
|
|
|
|
*/
|
|
|
|
for (SELECT_LEX *sl= lex->all_selects_list;
|
|
|
|
sl;
|
|
|
|
sl= sl->next_select_in_list())
|
|
|
|
{
|
|
|
|
sl->context.error_processor= &view_error_processor;
|
|
|
|
sl->context.error_processor_data= (void *)table;
|
|
|
|
}
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
|
|
|
check MERGE algorithm ability
|
|
|
|
- algorithm is not explicit TEMPORARY TABLE
|
2004-10-07 00:45:06 +02:00
|
|
|
- VIEW SELECT allow merging
|
2004-07-16 00:15:55 +02:00
|
|
|
- VIEW used in subquery or command support MERGE algorithm
|
|
|
|
*/
|
2004-09-03 20:43:04 +02:00
|
|
|
if (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
|
2004-07-16 00:15:55 +02:00
|
|
|
lex->can_be_merged() &&
|
|
|
|
(table->select_lex->master_unit() != &old_lex->unit ||
|
2004-08-24 21:51:23 +02:00
|
|
|
old_lex->can_use_merged()) &&
|
|
|
|
!old_lex->can_not_use_merged())
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2005-07-04 02:42:33 +02:00
|
|
|
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
|
2006-04-22 09:54:25 +02:00
|
|
|
/*
|
|
|
|
Currently 'view_main_select_tables' differs from 'view_tables'
|
|
|
|
only then view has CONVERT_TZ() function in its select list.
|
|
|
|
This may change in future, for example if we enable merging
|
|
|
|
of views with subqueries in select list.
|
|
|
|
*/
|
|
|
|
TABLE_LIST *view_main_select_tables=
|
|
|
|
(TABLE_LIST*)lex->select_lex.table_list.first;
|
2004-07-16 00:15:55 +02:00
|
|
|
/* lex should contain at least one table */
|
2006-04-22 09:54:25 +02:00
|
|
|
DBUG_ASSERT(view_main_select_tables != 0);
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
|
2004-08-24 21:51:23 +02:00
|
|
|
DBUG_PRINT("info", ("algorithm: MERGE"));
|
2004-07-22 16:52:04 +02:00
|
|
|
table->updatable= (table->updatable_view != 0);
|
2005-07-01 06:05:42 +02:00
|
|
|
table->effective_with_check=
|
|
|
|
old_lex->get_effective_with_check(table);
|
2006-04-22 09:54:25 +02:00
|
|
|
table->merge_underlying_list= view_main_select_tables;
|
2005-10-27 23:18:23 +02:00
|
|
|
/*
|
|
|
|
Let us set proper lock type for tables of the view's main select
|
|
|
|
since we may want to perform update or insert on view. This won't
|
|
|
|
work for view containing union. But this is ok since we don't
|
|
|
|
allow insert and update on such views anyway.
|
|
|
|
|
|
|
|
Also we fill correct wanted privileges.
|
|
|
|
*/
|
|
|
|
for (tbl= table->merge_underlying_list; tbl; tbl= tbl->next_local)
|
|
|
|
{
|
|
|
|
tbl->lock_type= table->lock_type;
|
|
|
|
tbl->grant.want_privilege= top_view->grant.orig_want_privilege;
|
|
|
|
}
|
2005-07-01 06:05:42 +02:00
|
|
|
|
|
|
|
/* prepare view context */
|
2006-04-22 09:54:25 +02:00
|
|
|
lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
|
2005-07-01 06:05:42 +02:00
|
|
|
lex->select_lex.context.outer_context= 0;
|
|
|
|
lex->select_lex.context.select_lex= table->select_lex;
|
2005-08-13 16:06:30 +02:00
|
|
|
lex->select_lex.select_n_having_items+=
|
|
|
|
table->select_lex->select_n_having_items;
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
2005-05-05 17:49:15 +02:00
|
|
|
Tables of the main select of the view should be marked as belonging
|
|
|
|
to the same select as original view (again we can use LEX::select_lex
|
|
|
|
for this purprose because we don't support MERGE algorithm for views
|
|
|
|
with unions).
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2005-05-05 17:49:15 +02:00
|
|
|
for (tbl= lex->select_lex.get_table_list(); tbl; tbl= tbl->next_local)
|
2005-04-03 00:23:45 +02:00
|
|
|
tbl->select_lex= table->select_lex;
|
|
|
|
|
2004-09-14 18:28:29 +02:00
|
|
|
{
|
2006-04-22 09:54:25 +02:00
|
|
|
if (view_main_select_tables->next_local)
|
2005-08-13 16:06:30 +02:00
|
|
|
{
|
2005-05-11 01:31:13 +02:00
|
|
|
table->multitable_view= TRUE;
|
2005-08-13 16:06:30 +02:00
|
|
|
if (table->belong_to_view)
|
|
|
|
table->belong_to_view->multitable_view= TRUE;
|
|
|
|
}
|
2004-09-14 18:28:29 +02:00
|
|
|
/* make nested join structure for view tables */
|
|
|
|
NESTED_JOIN *nested_join;
|
|
|
|
if (!(nested_join= table->nested_join=
|
|
|
|
(NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
|
|
|
|
goto err;
|
|
|
|
nested_join->join_list= view_select->top_join_list;
|
|
|
|
|
|
|
|
/* re-nest tables of VIEW */
|
2005-07-04 02:42:33 +02:00
|
|
|
ti.rewind();
|
|
|
|
while ((tbl= ti++))
|
2004-09-14 18:28:29 +02:00
|
|
|
{
|
2005-07-04 02:42:33 +02:00
|
|
|
tbl->join_list= &nested_join->join_list;
|
|
|
|
tbl->embedding= table;
|
2004-09-14 18:28:29 +02:00
|
|
|
}
|
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2005-10-27 23:18:23 +02:00
|
|
|
/* Store WHERE clause for post-processing in setup_underlying */
|
2004-09-14 18:28:29 +02:00
|
|
|
table->where= view_select->where;
|
2004-10-07 21:54:31 +02:00
|
|
|
/*
|
2005-04-22 22:13:46 +02:00
|
|
|
Add subqueries units to SELECT into which we merging current view.
|
|
|
|
unit(->next)* chain starts with subqueries that are used by this
|
|
|
|
view and continues with subqueries that are used by other views.
|
|
|
|
We must not add any subquery twice (otherwise we'll form a loop),
|
2005-07-01 06:05:42 +02:00
|
|
|
to do this we remember in end_unit the first subquery that has
|
2005-04-22 22:13:46 +02:00
|
|
|
been already added.
|
2005-07-01 06:05:42 +02:00
|
|
|
|
2004-10-07 21:54:31 +02:00
|
|
|
NOTE: we do not support UNION here, so we take only one select
|
|
|
|
*/
|
2005-04-22 22:13:46 +02:00
|
|
|
SELECT_LEX_NODE *end_unit= table->select_lex->slave;
|
2005-04-23 04:55:43 +02:00
|
|
|
SELECT_LEX_UNIT *next_unit;
|
2004-10-07 21:54:31 +02:00
|
|
|
for (SELECT_LEX_UNIT *unit= lex->select_lex.first_inner_unit();
|
|
|
|
unit;
|
2005-04-23 04:55:43 +02:00
|
|
|
unit= next_unit)
|
2004-10-07 21:54:31 +02:00
|
|
|
{
|
2005-04-22 22:13:46 +02:00
|
|
|
if (unit == end_unit)
|
|
|
|
break;
|
2005-04-23 04:55:43 +02:00
|
|
|
SELECT_LEX_NODE *save_slave= unit->slave;
|
|
|
|
next_unit= unit->next_unit();
|
2004-10-07 21:54:31 +02:00
|
|
|
unit->include_down(table->select_lex);
|
|
|
|
unit->slave= save_slave; // fix include_down initialisation
|
|
|
|
}
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
/*
|
|
|
|
This SELECT_LEX will be linked in global SELECT_LEX list
|
|
|
|
to make it processed by mysql_handle_derived(),
|
|
|
|
but it will not be included to SELECT_LEX tree, because it
|
|
|
|
will not be executed
|
|
|
|
*/
|
|
|
|
goto ok;
|
|
|
|
}
|
|
|
|
|
2004-09-03 20:43:04 +02:00
|
|
|
table->effective_algorithm= VIEW_ALGORITHM_TMPTABLE;
|
2004-08-24 21:51:23 +02:00
|
|
|
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
|
2004-09-14 18:28:29 +02:00
|
|
|
view_select->linkage= DERIVED_TABLE_TYPE;
|
2004-07-22 16:52:04 +02:00
|
|
|
table->updatable= 0;
|
2004-10-07 14:43:04 +02:00
|
|
|
table->effective_with_check= VIEW_CHECK_NONE;
|
2004-12-06 16:15:54 +01:00
|
|
|
old_lex->subqueries= TRUE;
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
/* SELECT tree link */
|
|
|
|
lex->unit.include_down(table->select_lex);
|
2004-09-14 18:28:29 +02:00
|
|
|
lex->unit.slave= view_select; // fix include_down initialisation
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
table->derived= &lex->unit;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
ok:
|
|
|
|
/* global SELECT list linking */
|
2004-09-14 18:28:29 +02:00
|
|
|
end= view_select; // primary SELECT_LEX is always last
|
2004-07-16 00:15:55 +02:00
|
|
|
end->link_next= old_lex->all_selects_list;
|
|
|
|
old_lex->all_selects_list->link_prev= &end->link_next;
|
|
|
|
old_lex->all_selects_list= lex->all_selects_list;
|
|
|
|
lex->all_selects_list->link_prev=
|
|
|
|
(st_select_lex_node**)&old_lex->all_selects_list;
|
|
|
|
|
Better approach for prelocking of tables for stored routines execution
and some SP-related cleanups.
- We don't have separate stage for calculation of list of tables
to be prelocked and doing implicit LOCK/UNLOCK any more.
Instead we calculate this list at open_tables() and do implicit
LOCK in lock_tables() (and UNLOCK in close_thread_tables()).
Also now we support cases when same table (with same alias) is
used several times in the same query in SP.
- Cleaned up execution of SP. Moved all common code which handles
LEX and does preparations before statement execution or complex
expression evaluation to auxilary sp_lex_keeper class. Now
all statements in SP (and corresponding instructions) that
evaluate expression which can contain subquery have their
own LEX.
mysql-test/r/lock.result:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/r/mysqldump.result:
Added dropping of view which is used in test to its beginning.
mysql-test/r/sp.result:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Replaced wrong results of test for bug #5240 with correct results after
fixing bug in handling of cursors.
mysql-test/t/lock.test:
Replaced wrong error code with the correct one after fixing bug in
SP-locking.
mysql-test/t/mysqldump.test:
Added dropping of view which is used in test to its beginning.
mysql-test/t/sp.test:
Added tests for improved SP-locking.
Temporarily disabled tests for SHOW PROCEDURE STATUS and alike
(Until Monty will allow to open mysql.proc under LOCK TABLES without
mentioning it in lock list).
Removed test for bug #1654 since we already test exactly this function
in one of SP-locking tests.
Removed comment about cursor's wrong behavior in test for bug #5240
after fixing bug which was its cause.
sql/item_func.cc:
Removed comment which is no longer true.
sql/mysql_priv.h:
Changed open_tables() signature.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sp.cc:
sp_find_procedure():
Added one more parameter which enforces cache only lookup.
sp_merge_hash():
Now uses its return value to indicate that first of two hashes changed
as result of merge.
sp_cache_routines():
This function caches all stored routines used in query now.
sql/sp.h:
- sp_find_procedure() now has one more parameter which enforces cache only
lookup.
- sp_merge_hash() now uses its return value to indicate that first of two
hashes changed as result of merge.
- sp_cache_routines() caches all stored routines now. So it does not need
third argument any more.
sql/sp_head.cc:
sp_head::sp_head():
Added initialization of new m_spfuns and m_spprocs members.
sp_head::execute():
Let us save/restore part of thread context which can be damaged by
execution of instructions.
sp_head::execute_function()/execute_procedure():
Now it is responsibility of caller to close tables used in
subqueries which are passed as routine parameters.
sp_head::restore_lex():
Let us accumulate information about routines used by this one
in new m_spfuns, m_spprocs hashes.
sp_lex_keeper::reset_lex_and_exec_core()
Main method of new auxilary sp_lex_keeper class to which instructions
delegate responsibility for handling LEX and preparations before
executing statement or calculating complex expression.
Since all instructions which calculate complex expression or execute
command now use sp_lex_keeper they have to implement
sp_instr::exec_core() method. Most of instruction specific logic
has moved from sp_instr::execute() to this new method.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sp_merge_table_list() became sp_head::merge_table_list() method. It
also treats sp_head::m_sptabs as multi-set of tables now.
sp_hash_to_table_list() became sp_head::add_used_tables_to_table_list().
It takes into account that sp_head::m_sptabs is multi-set and allocates
object into persistent arena of PS.
Removed sp_merge_table_hash(), sp_open_and_lock_tables(),
sp_unlock_tables(), sp_merge_routine_tables() methods since they are not
used by new prelocking mechanism.
Added sp_add_sp_tables_to_table_list() which serves for adding tables needed
by routines used in query to the query table list for prelocking.
sql/sp_head.h:
class sp_head:
- Added m_spfuns, m_spprocs members for storing names of routines used
by this routine.
- Added add_used_tables_to_table_list() method which allows to add
tables needed by this routine to query's table list.
- Converted sp_merge_table_list() to sp_head::merge_table_list() method.
- Changed semantics of THD::m_sptabs. Now it is multi-set which contains
only tables which are used by this routine and not routines that are
called from this one.
Removed sp_merge_routine_tables(), sp_merge_table_hash(),
sp_open_and_lock_tables(), sp_unlock_tables() calls since they are not
used for our prelocking list calculation.
Added auxilary sp_lex_keeper class to which instructions delegate
responsibility for handling LEX and preparations before executing
statement or calculating complex expression. This class uses
new sp_instr::exec_core() method which is responsible for executing
instruction's core function after all preparations were made.
All instructions which hold and calculate complex expression now have
their own LEX (by aggregating sp_lex_keeper instance). sp_instr_stmt
now uses sp_lex_keeper too.
Removed sp_instr_set_user_var class which is no longer used, because
nowdays we allow execution of statements in stored functions and
triggers.
sql/sp_rcontext.cc:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sp_rcontext.h:
Now sp_cursor holds pointer to sp_lex_keeper instead of LEX.
sql/sql_acl.cc:
acl_init(), grant_init():
Now we use simple_open_n_lock_tables() instead of explicit
calls to open_tables() and mysql_lock_tables().
sql/sql_base.cc:
Implemented support for execution of statements in "prelocked" mode.
When we have statement which uses stored routines explicitly or
implicitly (via views or triggers) we have to open and lock all tables
for these routines at the same time as tables for the main statement.
In fact we have to do implicit LOCK TABLES at the begining of such
statement and implict UNLOCK TABLES at its end. We call such mode
"prelocked".
When open_tables() is called for the statement tables which are needed
for execution of routines used by it are added to its tables list
(this process also caches all routines used). Implicit use of routines
is discovered when we open view or table with trigger and apropriate
tables are added to the table list at this moment. Statement which has
such extra tables in its list (well actually any that uses functions)
is marked as requiring prelocked mode for its execution.
When lock_tables() sees such statement it will issue implicit LOCK TABLES
for this extended table list instead of doing usual locking, it will also
set THD::prelocked_mode to indicate that we are in prelocked mode.
When open_tables()/lock_tables() are called for statement of stored
routine (substatement), they notice that we are running in prelocked mode
and use one of prelocked tables from those that are not used by upper
levels of execution.
close_thread_tables() for substatement won't really close tables used
but will mark them as free for reuse instead.
Finally when close_thread_tables() is called for the main statement it
really unlocks and closes all tables used.
Everything will work even if one uses such statement under real LOCK
TABLES (we are simply not doing implicit LOCK/UNLOCK in this case).
sql/sql_class.cc:
Added initialization of THD::prelocked_mode member.
sql/sql_class.h:
- Added prelocked_mode_type enum and THD::prelocked_mode member
which are used for indication whenever "prelocked mode" is on
(i.e. that statement uses stored routines and is executed under
implicit LOCK TABLES).
- Removed THD::shortcut_make_view which is no longer needed.
We use TABLE_LIST::prelocking_placeholder for the same purprose
now.
sql/sql_handler.cc:
Changed open_tables() invocation.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_lex.cc:
lex_start():
Added initialization of LEX::query_tables_own_last.
Unused LEX::sptabs member was removed.
st_lex::unlink_first_table()/link_first_table_back():
We should update LEX::query_tables_last properly if table list
contains(ed) only one element.
sql/sql_lex.h:
LEX:
- Removed sptabs member since it is no longer used.
- Added query_tables_own_last member, which if non-0 indicates that
statement requires prelocking (implicit LOCK TABLES) for its execution
and points to last own element in query table list. If it is zero
then this query does not need prelocking.
- Added requires_prelocking(), mark_as_requiring_prelocking(),
first_not_own_table() inline methods to incapsulate and simplify
usage of this new member.
sql/sql_parse.cc:
dispatch_command():
To properly leave prelocked mode when needed we should call
close_thread_tables() even if there are no open tables.
mysql_execute_command():
- Removed part of function which were responsible for doing implicit
LOCK TABLES before statement execution if statement used stored
routines (and doing UNLOCK TABLES at the end).
Now we do all this in open_tables()/lock_tables()/close_thread_tables()
instead.
- It is also sensible to reset errors before execution of statement
which uses routines.
- SQLCOM_DO, SQLCOM_SET_OPTION, SQLCOM_CALL
We should always try to open tables because even if statement has empty
table list, it can call routines using tables, which should be preopened
before statement execution.
- SQLCOM_CALL
We should not look up routine called in mysql.proc, since it should be
already cached by this moment by open_tables() call.
- SQLCOM_LOCK_TABLES
it is better to use simple_open_n_lock_tables() since we want to avoid
materialization of derived tables for this command.
sql/sql_prepare.cc:
mysql_test_update():
Changed open_tables() invocations. Now its 2nd parameter is in/out
since it can add elements to table list.
check_prepared_statement():
Since now we cache all routines used by statement in open_tables() we
don't need to do it explicitly.
mysql_stmt_prepare():
Now we should call close_thread_tables() when THD::lex points to the
LEX of statement which opened tables.
reset_stmt_for_execute():
Commented why we are resetting all tables in table list.
sql/sql_trigger.h:
Table_triggers_list::process_triggers():
We should surpress sending of ok packet when we are calling trigger's
routine, since now we allow statements in them.
sql/sql_update.cc:
Changed open_tables() invocations.
Now its 2nd parameter is in/out since it can add elements to table list.
sql/sql_view.cc:
mysql_make_view():
- Removed handling of routines used in view. Instead we add tables which
are needed for their execution to statement's table list in
open_tables().
- Now we use TABLE_LIST::prelocking_placeholder instead of
THD::shortcut_make_view for indicating that view is opened
only to discover which tables and routines it uses (this happens
when we build extended table list for prelocking). Also now we try
to avoid to modify main LEX in this case (except of its table list).
- Corrected small error we added tables to the table list of the main
LEX without updating its query_tables_last member properly.
sql/sql_yacc.yy:
Now each expression which is used in SP statements and can contain
subquery has its own LEX. This LEX is stored in corresponding sp_instr
object and used along with Item tree for expression calculation.
We don't need sp_instr_set_user_var() anymore since now we allow
execution of statements in stored functions and triggers.
sql/table.h:
Added TABLE_LIST::prelocking_placeholder member for distinguishing
elements of table list which does not belong to the statement itself
and added there only for prelocking (as they are to be used by routines
called by this statement).
sql/tztime.cc:
my_tz_init():
Now we use more simplier simple_open_n_lock_tables() call instead of
open_tables()/lock_tables() pair.
2005-03-04 14:35:28 +01:00
|
|
|
ok2:
|
2005-09-14 22:08:12 +02:00
|
|
|
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;
|
2005-11-01 14:54:30 +01:00
|
|
|
result= !table->prelocking_placeholder && table->prepare_security(thd);
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2006-05-04 21:19:31 +02:00
|
|
|
lex_end(thd->lex);
|
2005-11-01 14:54:30 +01:00
|
|
|
end:
|
2004-07-16 00:15:55 +02:00
|
|
|
if (arena)
|
2005-09-02 15:21:19 +02:00
|
|
|
thd->restore_active_arena(arena, &backup);
|
2005-11-01 14:54:30 +01:00
|
|
|
thd->lex= old_lex;
|
|
|
|
DBUG_RETURN(result);
|
|
|
|
|
|
|
|
err:
|
2006-05-04 21:19:31 +02:00
|
|
|
DBUG_ASSERT(thd->lex == table->view);
|
|
|
|
lex_end(thd->lex);
|
2005-03-04 18:54:24 +01:00
|
|
|
delete table->view;
|
2004-07-16 00:15:55 +02:00
|
|
|
table->view= 0; // now it is not VIEW placeholder
|
2005-11-01 14:54:30 +01:00
|
|
|
result= 1;
|
|
|
|
goto end;
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
drop view
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mysql_drop_view()
|
|
|
|
thd - thread handler
|
|
|
|
views - views to delete
|
|
|
|
drop_mode - cascade/check
|
|
|
|
|
|
|
|
RETURN VALUE
|
2004-10-20 03:04:37 +02:00
|
|
|
FALSE OK
|
|
|
|
TRUE Error
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
2004-09-03 20:43:04 +02:00
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
char path[FN_REFLEN];
|
|
|
|
TABLE_LIST *view;
|
2005-12-21 19:18:40 +01:00
|
|
|
enum legacy_db_type not_used;
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
DBUG_ENTER("mysql_drop_view");
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
for (view= views; view; view= view->next_local)
|
|
|
|
{
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
TABLE_SHARE *share;
|
2005-11-24 05:17:38 +01:00
|
|
|
bool type= 0;
|
2005-12-31 06:01:26 +01:00
|
|
|
build_table_filename(path, sizeof(path),
|
|
|
|
view->db, view->table_name, reg_ext);
|
2004-07-16 00:15:55 +02:00
|
|
|
VOID(pthread_mutex_lock(&LOCK_open));
|
2005-11-03 15:10:11 +01:00
|
|
|
if (access(path, F_OK) ||
|
|
|
|
(type= (mysql_frm_type(thd, path, ¬_used) != FRMTYPE_VIEW)))
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
char name[FN_REFLEN];
|
2005-01-06 12:00:13 +01:00
|
|
|
my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
|
2004-07-16 00:15:55 +02:00
|
|
|
if (thd->lex->drop_if_exists)
|
|
|
|
{
|
|
|
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
|
|
|
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
|
|
|
|
name);
|
|
|
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (type)
|
2005-01-06 12:00:13 +01:00
|
|
|
my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
|
2004-07-16 00:15:55 +02:00
|
|
|
else
|
|
|
|
my_error(ER_BAD_TABLE_ERROR, MYF(0), name);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
if (my_delete(path, MYF(MY_WME)))
|
|
|
|
goto err;
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
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);
|
|
|
|
}
|
2005-01-27 13:21:37 +01:00
|
|
|
query_cache_invalidate3(thd, view, 0);
|
2005-07-12 19:44:32 +02:00
|
|
|
sp_cache_invalidate();
|
2004-07-16 00:15:55 +02:00
|
|
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
|
|
|
}
|
|
|
|
send_ok(thd);
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(FALSE);
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
err:
|
|
|
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(TRUE);
|
2004-07-16 00:15:55 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Check type of .frm if we are not going to parse it
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mysql_frm_type()
|
|
|
|
path path to file
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
FRMTYPE_ERROR error
|
|
|
|
FRMTYPE_TABLE table
|
|
|
|
FRMTYPE_VIEW view
|
|
|
|
*/
|
|
|
|
|
2005-12-21 19:18:40 +01:00
|
|
|
frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
File file;
|
2005-11-03 15:10:11 +01:00
|
|
|
uchar header[10]; //"TYPE=VIEW\n" it is 10 characters
|
|
|
|
int error;
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_ENTER("mysql_frm_type");
|
|
|
|
|
2005-11-03 15:10:11 +01:00
|
|
|
*dbt= DB_TYPE_UNKNOWN;
|
|
|
|
|
2005-09-18 21:43:28 +02:00
|
|
|
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_RETURN(FRMTYPE_ERROR);
|
2005-11-03 15:10:11 +01:00
|
|
|
error= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME | MY_NABP));
|
2004-07-16 00:15:55 +02:00
|
|
|
my_close(file, MYF(MY_WME));
|
2005-11-03 15:10:11 +01:00
|
|
|
|
|
|
|
if (error)
|
2004-09-03 20:43:04 +02:00
|
|
|
DBUG_RETURN(FRMTYPE_ERROR);
|
2005-11-03 15:10:11 +01:00
|
|
|
if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header)))
|
2004-09-03 20:43:04 +02:00
|
|
|
DBUG_RETURN(FRMTYPE_VIEW);
|
2005-11-03 15:10:11 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
This is just a check for DB_TYPE. We'll return default unknown type
|
|
|
|
if the following test is true (arg #3). This should not have effect
|
|
|
|
on return value from this function (default FRMTYPE_TABLE)
|
|
|
|
*/
|
|
|
|
if (header[0] != (uchar) 254 || header[1] != 1 ||
|
|
|
|
(header[2] != FRM_VER && header[2] != FRM_VER+1 &&
|
|
|
|
(header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
|
|
|
|
DBUG_RETURN(FRMTYPE_TABLE);
|
|
|
|
|
2005-12-21 19:18:40 +01:00
|
|
|
*dbt= (enum legacy_db_type) (uint) *(header + 3);
|
2004-09-03 20:43:04 +02:00
|
|
|
DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
check of key (primary or unique) presence in updatable view
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
check_key_in_view()
|
|
|
|
thd thread handler
|
|
|
|
view view for check with opened table
|
|
|
|
|
2004-10-07 00:45:06 +02:00
|
|
|
DESCRIPTION
|
2004-10-07 11:13:42 +02:00
|
|
|
If it is VIEW and query have LIMIT clause then check that undertlying
|
|
|
|
table of viey contain one of following:
|
2004-10-07 00:45:06 +02:00
|
|
|
1) primary key of underlying table
|
|
|
|
2) unique key underlying table with fields for which NULL value is
|
|
|
|
impossible
|
|
|
|
3) all fields of underlying table
|
|
|
|
|
2004-07-16 00:15:55 +02:00
|
|
|
RETURN
|
|
|
|
FALSE OK
|
|
|
|
TRUE view do not contain key or all fields
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
|
|
|
{
|
2004-09-03 20:43:04 +02:00
|
|
|
TABLE *table;
|
2005-07-01 06:05:42 +02:00
|
|
|
Field_translator *trans, *end_of_trans;
|
2004-09-03 20:43:04 +02:00
|
|
|
KEY *key_info, *key_info_end;
|
2005-07-01 06:05:42 +02:00
|
|
|
uint i;
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_ENTER("check_key_in_view");
|
2004-09-03 20:43:04 +02:00
|
|
|
|
2004-10-07 21:54:31 +02:00
|
|
|
/*
|
2004-11-11 20:18:10 +01:00
|
|
|
we do not support updatable UNIONs in VIEW, so we can check just limit of
|
2004-10-07 21:54:31 +02:00
|
|
|
LEX::select_lex
|
|
|
|
*/
|
Patch two (the final one) for Bug#7306 "the server side preparedStatement
error for LIMIT placeholder".
The patch adds grammar support for LIMIT ?, ? and changes the
type of ST_SELECT_LEX::select_limit,offset_limit from ha_rows to Item*,
so that it can point to Item_param.
mysql-test/include/ps_modify.inc:
Fix existing tests: now LIMIT can contain placeholders.
mysql-test/include/ps_query.inc:
Fix existing tests: now LIMIT can contain placeholders.
mysql-test/r/ps.result:
Add basic test coverage for LIMIT ?, ? and fix test results.
mysql-test/r/ps_2myisam.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_3innodb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_4heap.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_5merge.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_6bdb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_7ndb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/t/ps.test:
Add basic test coverage for LIMIT ?, ?.
sql/item.h:
Add a short-cut for (ulonglong) val_int() to Item.
Add a constructor to Item_int() that accepts ulonglong.
Simplify Item_uint constructor by using the c-tor above.
sql/item_subselect.cc:
Now select_limit has type Item *.
We can safely create an Item in Item_exists_subselect::fix_length_and_dec():
it will be allocated in runtime memory root and freed in the end of
execution.
sql/sp_head.cc:
Add a special initalization state for stored procedures to
be able to easily distinguish the first execution of a stored procedure
from prepared statement prepare.
sql/sql_class.h:
Introduce new state 'INITIALIZED_FOR_SP' to be able to easily distinguish
the first execution of a stored procedure from prepared statement prepare.
sql/sql_derived.cc:
- use unit->set_limit() to set unit->select_limit_cnt, offset_limit_cnt
evreryplace. Add a warning about use of set_limit in
mysql_derived_filling.
sql/sql_error.cc:
- use unit->set_limit() to set unit->select_limit_cnt, offset_limit_cnt
evreryplace.
- this change is also aware of bug#11095 "show warnings limit 0 returns
all rows instead of zero rows", so the one who merges the bugfix from
4.1 can use local version of sql_error.cc.
sql/sql_handler.cc:
- use unit->set_limit() to initalize
unit->select_limit_cnt,offset_limit_cnt everyplace.
sql/sql_lex.cc:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_lex.h:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_parse.cc:
- use unit->set_limit() to initalize
unit->select_limit_cnt,offset_limit_cnt everyplace.
- we can create an Item_int to set global limit of a statement:
it will be created in the runtime mem root and freed in the end of
execution.
sql/sql_repl.cc:
Use unit->set_limit to initialize limits.
sql/sql_select.cc:
- select_limit is now Item* so the proper way to check for default value
is to compare it with NULL.
sql/sql_union.cc:
Evaluate offset_limit_cnt using the new type of ST_SELECT_LEX::offset_limit
sql/sql_view.cc:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_yacc.yy:
Add grammar support for LIMIT ?, ? clause.
2005-06-07 12:11:36 +02:00
|
|
|
if ((!view->view && !view->belong_to_view) ||
|
|
|
|
thd->lex->sql_command == SQLCOM_INSERT ||
|
|
|
|
thd->lex->select_lex.select_limit == 0)
|
2004-10-07 11:13:42 +02:00
|
|
|
DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */
|
2004-09-03 20:43:04 +02:00
|
|
|
table= view->table;
|
2005-08-02 21:54:49 +02:00
|
|
|
view= view->top_table();
|
2004-09-03 20:43:04 +02:00
|
|
|
trans= view->field_translation;
|
2005-01-06 12:00:13 +01:00
|
|
|
key_info_end= (key_info= table->key_info)+ table->s->keys;
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2005-07-01 06:05:42 +02:00
|
|
|
end_of_trans= view->field_translation_end;
|
2004-09-15 22:42:56 +02:00
|
|
|
DBUG_ASSERT(table != 0 && view->field_translation != 0);
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2005-07-01 06:05:42 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
We should be sure that all fields are ready to get keys from them, but
|
|
|
|
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;
|
2006-02-08 18:08:18 +01:00
|
|
|
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
|
2005-07-01 06:05:42 +02:00
|
|
|
for (Field_translator *fld= trans; fld < end_of_trans; fld++)
|
|
|
|
{
|
|
|
|
if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item))
|
2005-08-12 11:17:27 +02:00
|
|
|
{
|
2005-09-14 09:53:09 +02:00
|
|
|
thd->set_query_id= save_set_query_id;
|
2005-07-01 06:05:42 +02:00
|
|
|
return TRUE;
|
2005-08-12 11:17:27 +02:00
|
|
|
}
|
2005-07-01 06:05:42 +02:00
|
|
|
}
|
|
|
|
thd->set_query_id= save_set_query_id;
|
2006-02-08 18:08:18 +01:00
|
|
|
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
|
2005-07-01 06:05:42 +02:00
|
|
|
}
|
2004-09-03 20:43:04 +02:00
|
|
|
/* Loop over all keys to see if a unique-not-null key is used */
|
|
|
|
for (;key_info != key_info_end ; key_info++)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-03 20:43:04 +02:00
|
|
|
if ((key_info->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
|
|
|
KEY_PART_INFO *key_part= key_info->key_part;
|
2004-09-03 20:43:04 +02:00
|
|
|
KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
|
|
|
|
|
|
|
|
/* check that all key parts are used */
|
|
|
|
for (;;)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2005-07-01 06:05:42 +02:00
|
|
|
Field_translator *k;
|
|
|
|
for (k= trans; k < end_of_trans; k++)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-16 22:45:20 +02:00
|
|
|
Item_field *field;
|
2005-07-01 06:05:42 +02:00
|
|
|
if ((field= k->item->filed_for_view_update()) &&
|
2004-09-16 22:45:20 +02:00
|
|
|
field->field == key_part->field)
|
2004-07-16 00:15:55 +02:00
|
|
|
break;
|
|
|
|
}
|
2005-07-01 06:05:42 +02:00
|
|
|
if (k == end_of_trans)
|
2004-09-03 20:43:04 +02:00
|
|
|
break; // Key is not possible
|
|
|
|
if (++key_part == key_part_end)
|
|
|
|
DBUG_RETURN(FALSE); // Found usable key
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-03 20:43:04 +02:00
|
|
|
DBUG_PRINT("info", ("checking if all fields of table are used"));
|
2004-07-16 00:15:55 +02:00
|
|
|
/* check all fields presence */
|
|
|
|
{
|
2004-09-03 20:43:04 +02:00
|
|
|
Field **field_ptr;
|
2005-07-01 06:05:42 +02:00
|
|
|
Field_translator *fld;
|
2004-09-03 20:43:04 +02:00
|
|
|
for (field_ptr= table->field; *field_ptr; field_ptr++)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2005-07-01 06:05:42 +02:00
|
|
|
for (fld= trans; fld < end_of_trans; fld++)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-16 22:45:20 +02:00
|
|
|
Item_field *field;
|
2005-07-01 06:05:42 +02:00
|
|
|
if ((field= fld->item->filed_for_view_update()) &&
|
2004-09-16 22:45:20 +02:00
|
|
|
field->field == *field_ptr)
|
2004-07-16 00:15:55 +02:00
|
|
|
break;
|
|
|
|
}
|
2005-07-01 06:05:42 +02:00
|
|
|
if (fld == end_of_trans) // If field didn't exists
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-03 20:43:04 +02:00
|
|
|
/*
|
2005-07-01 06:05:42 +02:00
|
|
|
Keys or all fields of underlying tables are not found => we have
|
2004-10-07 11:13:42 +02:00
|
|
|
to check variable updatable_views_with_limit to decide should we
|
|
|
|
issue an error or just a warning
|
2004-09-03 20:43:04 +02:00
|
|
|
*/
|
2004-10-07 11:13:42 +02:00
|
|
|
if (thd->variables.updatable_views_with_limit)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-10-07 11:13:42 +02:00
|
|
|
/* update allowed, but issue warning */
|
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
|
|
|
ER_WARN_VIEW_WITHOUT_KEY, ER(ER_WARN_VIEW_WITHOUT_KEY));
|
|
|
|
DBUG_RETURN(FALSE);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
2004-10-07 11:13:42 +02:00
|
|
|
/* prohibit update */
|
|
|
|
DBUG_RETURN(TRUE);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DBUG_RETURN(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
insert fields from VIEW (MERGE algorithm) into given list
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
insert_view_fields()
|
2005-07-01 06:05:42 +02:00
|
|
|
thd thread handler
|
2004-07-16 00:15:55 +02:00
|
|
|
list list for insertion
|
|
|
|
view view for processing
|
2004-09-15 22:42:56 +02:00
|
|
|
|
|
|
|
RETURN
|
post-merge fix
mysql-test/r/view.result:
changes in error number, and key in view processing
mysql-test/t/view.test:
changes in error number, and key in view processing
sql/mysql_priv.h:
changes functions
sql/sp.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_base.cc:
fixed finding table, taking in account join view, which can have not TABLE pointer
now we report to setup_tables(), are we setuping SELECT...INSERT and ennumerete insert table separately
sql/sql_delete.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_help.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_insert.cc:
fixed returning value of functions
sql/sql_load.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
removed second setup_tables call (merge)
sql/sql_olap.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_parse.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_prepare.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_select.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_update.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_view.cc:
returning value fixed
sql/sql_view.h:
returning value fixed
2004-11-25 01:23:13 +01:00
|
|
|
FALSE OK
|
|
|
|
TRUE error (is not sent to cliet)
|
2004-07-16 00:15:55 +02:00
|
|
|
*/
|
|
|
|
|
2005-07-01 06:05:42 +02:00
|
|
|
bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2005-07-01 06:05:42 +02:00
|
|
|
Field_translator *trans_end;
|
2004-09-14 18:28:29 +02:00
|
|
|
Field_translator *trans;
|
2004-07-16 00:15:55 +02:00
|
|
|
DBUG_ENTER("insert_view_fields");
|
2004-09-03 20:43:04 +02:00
|
|
|
|
|
|
|
if (!(trans= view->field_translation))
|
post-merge fix
mysql-test/r/view.result:
changes in error number, and key in view processing
mysql-test/t/view.test:
changes in error number, and key in view processing
sql/mysql_priv.h:
changes functions
sql/sp.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_base.cc:
fixed finding table, taking in account join view, which can have not TABLE pointer
now we report to setup_tables(), are we setuping SELECT...INSERT and ennumerete insert table separately
sql/sql_delete.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_help.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_insert.cc:
fixed returning value of functions
sql/sql_load.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
removed second setup_tables call (merge)
sql/sql_olap.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_parse.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_prepare.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_select.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_update.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_view.cc:
returning value fixed
sql/sql_view.h:
returning value fixed
2004-11-25 01:23:13 +01:00
|
|
|
DBUG_RETURN(FALSE);
|
2005-07-01 06:05:42 +02:00
|
|
|
trans_end= view->field_translation_end;
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2005-07-01 06:05:42 +02:00
|
|
|
for (Field_translator *entry= trans; entry < trans_end; entry++)
|
2004-07-16 00:15:55 +02:00
|
|
|
{
|
2004-09-16 22:45:20 +02:00
|
|
|
Item_field *fld;
|
2005-07-01 06:05:42 +02:00
|
|
|
if ((fld= entry->item->filed_for_view_update()))
|
2004-09-16 22:45:20 +02:00
|
|
|
list->push_back(fld);
|
2004-09-15 22:42:56 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT");
|
post-merge fix
mysql-test/r/view.result:
changes in error number, and key in view processing
mysql-test/t/view.test:
changes in error number, and key in view processing
sql/mysql_priv.h:
changes functions
sql/sp.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_base.cc:
fixed finding table, taking in account join view, which can have not TABLE pointer
now we report to setup_tables(), are we setuping SELECT...INSERT and ennumerete insert table separately
sql/sql_delete.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_help.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_insert.cc:
fixed returning value of functions
sql/sql_load.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
removed second setup_tables call (merge)
sql/sql_olap.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_parse.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_prepare.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_select.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_update.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_view.cc:
returning value fixed
sql/sql_view.h:
returning value fixed
2004-11-25 01:23:13 +01:00
|
|
|
DBUG_RETURN(TRUE);
|
2004-09-15 22:42:56 +02:00
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
post-merge fix
mysql-test/r/view.result:
changes in error number, and key in view processing
mysql-test/t/view.test:
changes in error number, and key in view processing
sql/mysql_priv.h:
changes functions
sql/sp.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_base.cc:
fixed finding table, taking in account join view, which can have not TABLE pointer
now we report to setup_tables(), are we setuping SELECT...INSERT and ennumerete insert table separately
sql/sql_delete.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_help.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_insert.cc:
fixed returning value of functions
sql/sql_load.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
removed second setup_tables call (merge)
sql/sql_olap.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_parse.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_prepare.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_select.cc:
now we report to setup_tables(), are we setuping SELECT...INSERT
sql/sql_update.cc:
UPDATE->MULTIUPDATE switching fixed
sql/sql_view.cc:
returning value fixed
sql/sql_view.h:
returning value fixed
2004-11-25 01:23:13 +01:00
|
|
|
DBUG_RETURN(FALSE);
|
2004-07-16 00:15:55 +02:00
|
|
|
}
|
2004-10-28 18:37:25 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
checking view md5 check suum
|
|
|
|
|
|
|
|
SINOPSYS
|
|
|
|
view_checksum()
|
|
|
|
thd threar handler
|
|
|
|
view view for check
|
|
|
|
|
|
|
|
RETUIRN
|
|
|
|
HA_ADMIN_OK OK
|
|
|
|
HA_ADMIN_NOT_IMPLEMENTED it is not VIEW
|
|
|
|
HA_ADMIN_WRONG_CHECKSUM check sum is wrong
|
|
|
|
*/
|
|
|
|
|
|
|
|
int view_checksum(THD *thd, TABLE_LIST *view)
|
|
|
|
{
|
|
|
|
char md5[MD5_BUFF_LENGTH];
|
|
|
|
if (!view->view || view->md5.length != 32)
|
|
|
|
return HA_ADMIN_NOT_IMPLEMENTED;
|
|
|
|
view->calc_md5(md5);
|
|
|
|
return (strncmp(md5, view->md5.str, 32) ?
|
|
|
|
HA_ADMIN_WRONG_CHECKSUM :
|
|
|
|
HA_ADMIN_OK);
|
|
|
|
}
|
2005-09-16 17:13:21 +02:00
|
|
|
|
2005-09-18 21:43:28 +02:00
|
|
|
/*
|
|
|
|
rename view
|
2005-09-16 17:13:21 +02:00
|
|
|
|
2005-09-18 21:43:28 +02:00
|
|
|
Synopsis:
|
|
|
|
renames a view
|
2005-09-16 17:13:21 +02:00
|
|
|
|
2005-09-18 21:43:28 +02:00
|
|
|
Parameters:
|
|
|
|
thd thread handler
|
|
|
|
new_name new name of view
|
|
|
|
view view
|
2005-09-16 17:13:21 +02:00
|
|
|
|
2005-09-18 21:43:28 +02:00
|
|
|
Return values:
|
|
|
|
FALSE Ok
|
|
|
|
TRUE Error
|
|
|
|
*/
|
2005-09-16 17:13:21 +02:00
|
|
|
bool
|
|
|
|
mysql_rename_view(THD *thd,
|
2005-09-29 12:29:58 +02:00
|
|
|
const char *new_name,
|
|
|
|
TABLE_LIST *view)
|
2005-09-16 17:13:21 +02:00
|
|
|
{
|
|
|
|
LEX_STRING pathstr, file;
|
|
|
|
File_parser *parser;
|
|
|
|
char view_path[FN_REFLEN];
|
2005-09-29 12:29:58 +02:00
|
|
|
bool error= TRUE;
|
2005-09-16 17:13:21 +02:00
|
|
|
|
|
|
|
DBUG_ENTER("mysql_rename_view");
|
|
|
|
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
strxnmov(view_path, FN_REFLEN-1, mysql_data_home, "/", view->db, "/",
|
2005-09-16 17:13:21 +02:00
|
|
|
view->table_name, reg_ext, NullS);
|
|
|
|
(void) unpack_filename(view_path, view_path);
|
|
|
|
|
|
|
|
pathstr.str= (char *)view_path;
|
|
|
|
pathstr.length= strlen(view_path);
|
|
|
|
|
|
|
|
if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) &&
|
2005-09-29 12:29:58 +02:00
|
|
|
is_equal(&view_type, parser->type()))
|
|
|
|
{
|
2005-09-30 15:30:33 +02:00
|
|
|
TABLE_LIST view_def;
|
2005-09-16 17:13:21 +02:00
|
|
|
char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
|
|
|
|
|
2005-09-30 15:30:33 +02:00
|
|
|
/*
|
|
|
|
To be PS-friendly we should either to restore state of
|
|
|
|
TABLE_LIST object pointed by 'view' after using it for
|
|
|
|
view definition parsing or use temporary 'view_def'
|
|
|
|
object for it.
|
|
|
|
*/
|
|
|
|
bzero(&view_def, sizeof(view_def));
|
|
|
|
view_def.timestamp.str= view_def.timestamp_buffer;
|
|
|
|
view_def.view_suid= TRUE;
|
|
|
|
|
2005-09-16 17:13:21 +02:00
|
|
|
/* get view definition and source */
|
2005-09-30 15:30:33 +02:00
|
|
|
if (parser->parse((gptr)&view_def, thd->mem_root, view_parameters,
|
2005-11-20 19:47:07 +01:00
|
|
|
array_elements(view_parameters)-1,
|
|
|
|
&file_parser_dummy_hook))
|
2005-09-29 12:29:58 +02:00
|
|
|
goto err;
|
2005-09-16 17:13:21 +02:00
|
|
|
|
|
|
|
/* rename view and it's backups */
|
2005-09-18 21:43:28 +02:00
|
|
|
if (rename_in_schema_file(view->db, view->table_name, new_name,
|
2005-09-30 15:30:33 +02:00
|
|
|
view_def.revision - 1, num_view_backups))
|
2005-09-29 12:29:58 +02:00
|
|
|
goto err;
|
2005-09-16 17:13:21 +02:00
|
|
|
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
strxnmov(dir_buff, FN_REFLEN-1, mysql_data_home, "/", view->db, "/",
|
|
|
|
NullS);
|
2005-09-16 17:13:21 +02:00
|
|
|
(void) unpack_filename(dir_buff, dir_buff);
|
|
|
|
|
|
|
|
pathstr.str= (char*)dir_buff;
|
|
|
|
pathstr.length= strlen(dir_buff);
|
|
|
|
|
|
|
|
file.str= file_buff;
|
|
|
|
file.length= (strxnmov(file_buff, FN_REFLEN, new_name, reg_ext, NullS)
|
|
|
|
- file_buff);
|
|
|
|
|
|
|
|
if (sql_create_definition_file(&pathstr, &file, view_file_type,
|
2005-09-30 15:30:33 +02:00
|
|
|
(gptr)&view_def, view_parameters,
|
2005-09-29 12:29:58 +02:00
|
|
|
num_view_backups))
|
|
|
|
{
|
2005-09-16 17:13:21 +02:00
|
|
|
/* restore renamed view in case of error */
|
2005-09-18 21:43:28 +02:00
|
|
|
rename_in_schema_file(view->db, new_name, view->table_name,
|
2005-09-30 15:30:33 +02:00
|
|
|
view_def.revision - 1, num_view_backups);
|
2005-09-29 12:29:58 +02:00
|
|
|
goto err;
|
2005-09-16 17:13:21 +02:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
|
|
|
|
/* remove cache entries */
|
|
|
|
query_cache_invalidate3(thd, view, 0);
|
|
|
|
sp_cache_invalidate();
|
2005-09-29 12:29:58 +02:00
|
|
|
error= FALSE;
|
|
|
|
|
|
|
|
err:
|
|
|
|
DBUG_RETURN(error);
|
2005-09-16 17:13:21 +02:00
|
|
|
}
|