Below is the list of changes that have just been committed into a local
5.0 repository of serg. When serg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-03-21 20:48:16+01:00, serg@stripped +4 -0
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into sergbook.mysql.com:/usr/home/serg/Abk/mysql-5.0
MERGE: 1.2294.4.30
client/mysqldump.c@stripped, 2007-03-21 20:48:09+01:00, serg@stripped +0 -0
Auto merged
MERGE: 1.250.1.7
sql/item_timefunc.cc@stripped, 2007-03-21 20:48:09+01:00, serg@stripped +0 -0
Auto merged
MERGE: 1.133.1.3
sql/log_event.cc@stripped, 2007-03-21 20:48:10+01:00, serg@stripped +0 -0
Auto merged
MERGE: 1.216.1.1
sql/sp_head.cc@stripped, 2007-03-21 20:48:10+01:00, serg@stripped +0 -0
Auto merged
MERGE: 1.226.1.11
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: serg
# Host: sergbook.mysql.com
# Root: /usr/home/serg/Abk/mysql-5.0/RESYNC
--- 1.252/client/mysqldump.c 2007-03-21 20:48:25 +01:00
+++ 1.253/client/mysqldump.c 2007-03-21 20:48:25 +01:00
@@ -2,8 +2,7 @@
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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -112,7 +111,7 @@
static ulong opt_compatible_mode= 0;
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
-static uint opt_mysql_port= 0, err_len= 0, opt_master_data;
+static uint opt_mysql_port= 0, opt_master_data;
static my_string opt_mysql_unix_port=0;
static int first_error=0;
static DYNAMIC_STRING extended_row;
@@ -724,6 +723,7 @@
char *end= compatible_mode_normal_str;
int i;
ulong mode;
+ uint err_len;
opt_quoted= 1;
opt_set_charset= 0;
@@ -861,11 +861,11 @@
/*
** DB_error -- prints mysql error message and exits the program.
*/
-static void DB_error(MYSQL *mysql, const char *when)
+static void DB_error(MYSQL *mysql_arg, const char *when)
{
DBUG_ENTER("DB_error");
fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname,
- mysql_errno(mysql), mysql_error(mysql), when);
+ mysql_errno(mysql_arg), mysql_error(mysql_arg), when);
fflush(stderr);
safe_exit(EX_MYSQLERR);
DBUG_VOID_RETURN;
@@ -1193,7 +1193,7 @@
..., attribute_name_n, attribute_value_n, NullS)
xml_file - output file
sbeg - line beginning
- send - line ending
+ line_end - line ending
tag_name - XML tag name.
first_attribute_name - tag and first attribute
first_attribute_value - (Implied) value of first attribute
@@ -1213,7 +1213,8 @@
All attribute_value arguments will be quoted before output.
*/
-static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send,
+static void print_xml_tag(FILE * xml_file, const char* sbeg,
+ const char* line_end,
const char* tag_name,
const char* first_attribute_name, ...)
{
@@ -1243,7 +1244,7 @@
va_end(arg_list);
fputc('>', xml_file);
- fputs(send, xml_file);
+ fputs(line_end, xml_file);
check_io(xml_file);
}
@@ -1257,7 +1258,7 @@
sbeg - line beginning
stag_atr - tag and attribute
sval - value of attribute
- send - line ending
+ line_end - line ending
DESCRIPTION
Print tag with one attribute to the xml_file. Format is:
@@ -1269,7 +1270,7 @@
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
const char* stag_atr, const char* sval,
- const char* send)
+ const char* line_end)
{
fputs(sbeg, xml_file);
fputs("<", xml_file);
@@ -1277,7 +1278,7 @@
fputs("\"", xml_file);
print_quoted_xml(xml_file, sval, strlen(sval));
fputs("\" xsi:nil=\"true\" />", xml_file);
- fputs(send, xml_file);
+ fputs(line_end, xml_file);
check_io(xml_file);
}
@@ -2015,7 +2016,8 @@
*/
-static void dump_triggers_for_table(char *table, char *db)
+static void dump_triggers_for_table(char *table,
+ char *db __attribute__((unused)))
{
char *result_table;
char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3];
@@ -2024,7 +2026,6 @@
FILE *sql_file= md_result_file;
MYSQL_RES *result;
MYSQL_ROW row;
-
DBUG_ENTER("dump_triggers_for_table");
DBUG_PRINT("enter", ("db: %s, table: %s", db, table));
--- 1.227/sql/sp_head.cc 2007-03-21 20:48:25 +01:00
+++ 1.228/sql/sp_head.cc 2007-03-21 20:48:25 +01:00
@@ -2,8 +2,7 @@
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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -37,6 +36,7 @@
sp_map_result_type(enum enum_field_types type)
{
switch (type) {
+ case MYSQL_TYPE_BIT:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
@@ -59,6 +59,7 @@
sp_map_item_type(enum enum_field_types type)
{
switch (type) {
+ case MYSQL_TYPE_BIT:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
@@ -95,8 +96,6 @@
static String *
sp_get_item_value(THD *thd, Item *item, String *str)
{
- Item_result result_type= item->result_type();
-
switch (item->result_type()) {
case REAL_RESULT:
case INT_RESULT:
@@ -607,27 +606,6 @@
DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s",
m_type, m_name.str, m_params.str, m_body.str));
-#ifndef DBUG_OFF
- optimize();
- {
- String s;
- sp_instr *i;
- uint ip= 0;
- while ((i = get_instr(ip)))
- {
- char buf[8];
-
- sprintf(buf, "%4u: ", ip);
- s.append(buf);
- i->print(&s);
- s.append('\n');
- ip+= 1;
- }
- s.append('\0');
- DBUG_PRINT("info", ("Code %s\n%s", m_qname.str, s.ptr()));
- }
-#endif
-
if (m_type == TYPE_ENUM_FUNCTION)
ret= sp_create_function(thd, this);
else
@@ -1109,6 +1087,7 @@
ctx->enter_handler(hip);
thd->clear_error();
thd->killed= THD::NOT_KILLED;
+ thd->mysys_var->abort= 0;
continue;
}
}
@@ -1450,6 +1429,8 @@
{
binlog_buf.length(0);
binlog_buf.append(STRING_WITH_LEN("SELECT "));
+ append_identifier(thd, &binlog_buf, m_db.str, m_db.length);
+ binlog_buf.append('.');
append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
binlog_buf.append('(');
for (arg_no= 0; arg_no < argcount; arg_no++)
@@ -1484,8 +1465,24 @@
binlog_save_options= thd->options;
if (need_binlog_call)
{
+ query_id_t q;
reset_dynamic(&thd->user_var_events);
- mysql_bin_log.start_union_events(thd);
+ /*
+ In case of artificially constructed events for function calls
+ we have separate union for each such event and hence can't use
+ query_id of real calling statement as the start of all these
+ unions (this will break logic of replication of user-defined
+ variables). So we use artifical value which is guaranteed to
+ be greater than all query_id's of all statements belonging
+ to previous events/unions.
+ Possible alternative to this is logging of all function invocations
+ as one select and not resetting THD::user_var_events before
+ each invocation.
+ */
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ q= global_query_id;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ mysql_bin_log.start_union_events(thd, q + 1);
}
/*
@@ -1753,7 +1750,7 @@
DBUG_ENTER("sp_head::reset_lex");
LEX *sublex;
LEX *oldlex= thd->lex;
- my_lex_states state= oldlex->next_state; // Keep original next_state
+ my_lex_states org_next_state= oldlex->next_state;
(void)m_lex.push_front(oldlex);
thd->lex= sublex= new st_lex;
@@ -1762,10 +1759,10 @@
lex_start(thd, oldlex->buf, (ulong) (oldlex->end_of_query - oldlex->ptr));
/*
- * next_state is normally the same (0), but it happens that we swap lex in
- * "mid-sentence", so we must restore it.
+ next_state is normally the same (0), but it happens that we swap lex in
+ "mid-sentence", so we must restore it.
*/
- sublex->next_state= state;
+ sublex->next_state= org_next_state;
/* We must reset ptr and end_of_query again */
sublex->ptr= oldlex->ptr;
sublex->end_of_query= oldlex->end_of_query;
@@ -2175,7 +2172,7 @@
This is the main mark and move loop; it relies on the following methods
in sp_instr and its subclasses:
- opt_mark() Mark instruction as reachable (will recurse for jumps)
+ opt_mark() Mark instruction as reachable
opt_shortcut_jump() Shortcut jumps to the final destination;
used by opt_mark().
opt_move() Update moved instruction
@@ -2188,7 +2185,7 @@
sp_instr *i;
uint src, dst;
- opt_mark(0);
+ opt_mark();
bp.empty();
src= dst= 0;
@@ -2222,13 +2219,50 @@
bp.empty();
}
+void sp_head::add_mark_lead(uint ip, List<sp_instr> *leads)
+{
+ sp_instr *i= get_instr(ip);
+
+ if (i && ! i->marked)
+ leads->push_front(i);
+}
+
void
-sp_head::opt_mark(uint ip)
+sp_head::opt_mark()
{
+ uint ip;
sp_instr *i;
+ List<sp_instr> leads;
+
+ /*
+ Forward flow analysis algorithm in the instruction graph:
+ - first, add the entry point in the graph (the first instruction) to the
+ 'leads' list of paths to explore.
+ - while there are still leads to explore:
+ - pick one lead, and follow the path forward. Mark instruction reached.
+ Stop only if the end of the routine is reached, or the path converge
+ to code already explored (marked).
+ - while following a path, collect in the 'leads' list any fork to
+ another path (caused by conditional jumps instructions), so that these
+ paths can be explored as well.
+ */
+
+ /* Add the entry point */
+ i= get_instr(0);
+ leads.push_front(i);
+
+ /* For each path of code ... */
+ while (leads.elements != 0)
+ {
+ i= leads.pop();
- while ((i= get_instr(ip)) && !i->marked)
- ip= i->opt_mark(this);
+ /* Mark the entire path, collecting new leads. */
+ while (i && ! i->marked)
+ {
+ ip= i->opt_mark(this, & leads);
+ i= get_instr(ip);
+ }
+ }
}
@@ -2357,16 +2391,11 @@
m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
}
}
-
+
reinit_stmt_before_use(thd, m_lex);
- /*
- If requested check whenever we have access to tables in LEX's table list
- and open and lock them before executing instructtions core function.
- */
- if (open_tables &&
- (check_table_access(thd, SELECT_ACL, m_lex->query_tables, 0) ||
- open_and_lock_tables(thd, m_lex->query_tables)))
- res= -1;
+
+ if (open_tables)
+ res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables, nextp);
if (!res)
res= instr->exec_core(thd, nextp);
@@ -2415,6 +2444,33 @@
sp_instr class functions
*/
+int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables,
+ uint *nextp)
+{
+ int result;
+
+ /*
+ Check whenever we have access to tables for this statement
+ and open and lock them before executing instructions core function.
+ */
+ if (check_table_access(thd, SELECT_ACL, tables, 0)
+ || open_and_lock_tables(thd, tables))
+ {
+ get_cont_dest(nextp);
+ result= -1;
+ }
+ else
+ result= 0;
+
+ return result;
+}
+
+void sp_instr::get_cont_dest(uint *nextp)
+{
+ *nextp= m_ip+1;
+}
+
+
int sp_instr::exec_core(THD *thd, uint *nextp)
{
DBUG_ASSERT(0);
@@ -2595,6 +2651,15 @@
value->print(str);
}
+/*
+ sp_instr_opt_meta
+*/
+
+void sp_instr_opt_meta::get_cont_dest(uint *nextp)
+{
+ *nextp= m_cont_dest;
+}
+
/*
sp_instr_jump class functions
@@ -2621,7 +2686,7 @@
}
uint
-sp_instr_jump::opt_mark(sp_head *sp)
+sp_instr_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
{
m_dest= opt_shortcut_jump(sp, this);
if (m_dest != m_ip+1) /* Jumping to following instruction? */
@@ -2715,7 +2780,7 @@
uint
-sp_instr_jump_if_not::opt_mark(sp_head *sp)
+sp_instr_jump_if_not::opt_mark(sp_head *sp, List<sp_instr> *leads)
{
sp_instr *i;
@@ -2725,13 +2790,13 @@
m_dest= i->opt_shortcut_jump(sp, this);
m_optdest= sp->get_instr(m_dest);
}
- sp->opt_mark(m_dest);
+ sp->add_mark_lead(m_dest, leads);
if ((i= sp->get_instr(m_cont_dest)))
{
m_cont_dest= i->opt_shortcut_jump(sp, this);
m_cont_optdest= sp->get_instr(m_cont_dest);
}
- sp->opt_mark(m_cont_dest);
+ sp->add_mark_lead(m_cont_dest, leads);
return m_ip+1;
}
@@ -2852,7 +2917,7 @@
uint
-sp_instr_hpush_jump::opt_mark(sp_head *sp)
+sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
{
sp_instr *i;
@@ -2862,7 +2927,7 @@
m_dest= i->opt_shortcut_jump(sp, this);
m_optdest= sp->get_instr(m_dest);
}
- sp->opt_mark(m_dest);
+ sp->add_mark_lead(m_dest, leads);
return m_ip+1;
}
@@ -2927,15 +2992,13 @@
uint
-sp_instr_hreturn::opt_mark(sp_head *sp)
+sp_instr_hreturn::opt_mark(sp_head *sp, List<sp_instr> *leads)
{
if (m_dest)
- return sp_instr_jump::opt_mark(sp);
- else
- {
- marked= 1;
- return UINT_MAX;
- }
+ return sp_instr_jump::opt_mark(sp, leads);
+
+ marked= 1;
+ return UINT_MAX;
}
@@ -3278,7 +3341,7 @@
}
uint
-sp_instr_set_case_expr::opt_mark(sp_head *sp)
+sp_instr_set_case_expr::opt_mark(sp_head *sp, List<sp_instr> *leads)
{
sp_instr *i;
@@ -3288,7 +3351,7 @@
m_cont_dest= i->opt_shortcut_jump(sp, this);
m_cont_optdest= sp->get_instr(m_cont_dest);
}
- sp->opt_mark(m_cont_dest);
+ sp->add_mark_lead(m_cont_dest, leads);
return m_ip+1;
}
| Thread |
|---|
| • bk commit into 5.0 tree (serg:1.2487) | Sergei Golubchik | 21 Mar |