Below is the list of changes that have just been committed into a local
5.1 repository of monty. When monty 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-06-21 11:13:10+03:00, monty@stripped +21 -0
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into mysql.com:/home/my/mysql-5.1
MERGE: 1.2482.18.9
client/mysqltest.c@stripped, 2007-06-21 10:42:05+03:00, monty@stripped +0 -16
Auto merged
MERGE: 1.301.2.4
mysql-test/lib/mtr_report.pl@stripped, 2007-06-21 11:13:07+03:00, monty@stripped +0
-65
Use remote version
MERGE: 1.47.1.2
mysql-test/mysql-test-run-shell.sh@stripped, 2007-06-21 10:42:05+03:00,
monty@stripped +0 -7
Auto merged
MERGE: 1.340.1.1
mysql-test/t/disabled.def@stripped, 2007-06-21 10:42:05+03:00, monty@stripped +0 -3
Auto merged
MERGE: 1.253.3.1
mysys/array.c@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0 -9
Auto merged
MERGE: 1.18.1.1
mysys/hash.c@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0 -5
Auto merged
MERGE: 1.55.1.1
mysys/my_compress.c@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0 -2
Auto merged
MERGE: 1.16.1.1
mysys/my_conio.c@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0 -4
Auto merged
MERGE: 1.4.1.1
mysys/my_quick.c@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0 -1
Auto merged
MERGE: 1.7.2.1
sql/ha_ndbcluster_binlog.cc@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0
-10
Auto merged
MERGE: 1.119.1.2
sql/ha_partition.cc@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0 -1
Auto merged
MERGE: 1.92.1.2
sql/log.cc@stripped, 2007-06-21 10:42:06+03:00, monty@stripped +0 -1
Auto merged
MERGE: 1.282.1.3
sql/slave.cc@stripped, 2007-06-21 10:42:07+03:00, monty@stripped +0 -2
Auto merged
MERGE: 1.308.1.1
sql/sql_class.cc@stripped, 2007-06-21 10:42:07+03:00, monty@stripped +0 -1
Auto merged
MERGE: 1.335.1.4
sql/sql_map.cc@stripped, 2007-06-21 10:42:07+03:00, monty@stripped +0 -2
Auto merged
MERGE: 1.20.2.1
sql/sql_plugin.cc@stripped, 2007-06-21 10:42:07+03:00, monty@stripped +0 -3
Auto merged
MERGE: 1.66.1.4
sql/stacktrace.c@stripped, 2007-06-21 10:42:07+03:00, monty@stripped +0 -5
Auto merged
MERGE: 1.28.1.1
storage/blackhole/ha_blackhole.cc@stripped, 2007-06-21 10:42:07+03:00, monty@stripped
+0 -2
Auto merged
MERGE: 1.52.1.1
storage/example/ha_example.cc@stripped, 2007-06-21 10:42:08+03:00, monty@stripped +0
-1
Auto merged
MERGE: 1.57.1.1
strings/ctype-ucs2.c@stripped, 2007-06-21 10:42:08+03:00, monty@stripped +0 -3
Auto merged
MERGE: 1.69.2.2
support-files/compiler_warnings.supp@stripped, 2007-06-21 10:42:08+03:00,
monty@stripped +0 -8
Auto merged
MERGE: 1.11.1.1
# 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: monty
# Host: nosik.monty.fi
# Root: /home/my/mysql-5.1/RESYNC
--- 1.283/sql/log.cc 2007-05-29 09:26:47 +03:00
+++ 1.284/sql/log.cc 2007-06-21 10:42:06 +03:00
@@ -296,6 +296,8 @@
table->db= log_thd->db;
table->db_length= log_thd->db_length;
+ lex_start(log_thd);
+ log_thd->clear_error();
if (simple_open_n_lock_tables(log_thd, table) ||
table->table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||
table->table->file->ha_rnd_init(0))
@@ -305,6 +307,9 @@
table->table->use_all_columns();
table->table->locked_by_logger= TRUE;
table->table->no_replicate= TRUE;
+
+ /* Honor next number columns if present */
+ table->table->next_number_field= table->table->found_next_number_field;
}
/* restore thread settings */
if (curr)
@@ -438,6 +443,7 @@
CHARSET_INFO *client_cs)
{
TABLE *table= general_log.table;
+ uint field_index;
/*
"INSERT INTO general_log" can generate warning sometimes.
@@ -488,6 +494,12 @@
table->field[4]->set_notnull();
table->field[5]->set_notnull();
+ /* Set any extra columns to their default values */
+ for (field_index= 6 ; field_index < table->s->fields ; field_index++)
+ {
+ table->field[field_index]->set_default();
+ }
+
/* log table entries are not replicated at the moment */
tmp_disable_binlog(current_thd);
@@ -1329,6 +1341,7 @@
/* close the table */
log_thd->store_globals();
table->table->file->ha_rnd_end();
+ table->table->file->ha_release_auto_increment();
/* discard logger mark before unlock*/
table->table->locked_by_logger= FALSE;
close_thread_tables(log_thd, lock_in_use);
--- 1.336/sql/sql_class.cc 2007-05-29 21:07:46 +03:00
+++ 1.337/sql/sql_class.cc 2007-06-21 10:42:07 +03:00
@@ -59,8 +59,8 @@
/* Used templates */
template class List<Key>;
template class List_iterator<Key>;
-template class List<key_part_spec>;
-template class List_iterator<key_part_spec>;
+template class List<Key_part_spec>;
+template class List_iterator<Key_part_spec>;
template class List<Alter_drop>;
template class List_iterator<Alter_drop>;
template class List<Alter_column>;
@@ -86,11 +86,45 @@
my_free((char*) entry,MYF(0));
}
-bool key_part_spec::operator==(const key_part_spec& other) const
+bool Key_part_spec::operator==(const Key_part_spec& other) const
{
return length == other.length && !strcmp(field_name, other.field_name);
}
+/**
+ Construct an (almost) deep copy of this key. Only those
+ elements that are known to never change are not copied.
+ If out of memory, a partial copy is returned and an error is set
+ in THD.
+*/
+
+Key::Key(const Key &rhs, MEM_ROOT *mem_root)
+ :type(rhs.type),
+ key_create_info(rhs.key_create_info),
+ columns(rhs.columns, mem_root),
+ name(rhs.name),
+ generated(rhs.generated)
+{
+ list_copy_and_replace_each_value(columns, mem_root);
+}
+
+/**
+ Construct an (almost) deep copy of this foreign key. Only those
+ elements that are known to never change are not copied.
+ If out of memory, a partial copy is returned and an error is set
+ in THD.
+*/
+
+Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
+ :Key(rhs),
+ ref_table(rhs.ref_table),
+ ref_columns(rhs.ref_columns),
+ delete_opt(rhs.delete_opt),
+ update_opt(rhs.update_opt),
+ match_opt(rhs.match_opt)
+{
+ list_copy_and_replace_each_value(ref_columns, mem_root);
+}
/*
Test if a foreign key (= generated key) is a prefix of the given key
@@ -126,9 +160,9 @@
if (a->columns.elements > b->columns.elements)
return TRUE; // Can't be prefix
- List_iterator<key_part_spec> col_it1(a->columns);
- List_iterator<key_part_spec> col_it2(b->columns);
- const key_part_spec *col1, *col2;
+ List_iterator<Key_part_spec> col_it1(a->columns);
+ List_iterator<Key_part_spec> col_it2(b->columns);
+ const Key_part_spec *col1, *col2;
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
while ((col1= col_it1++))
@@ -308,7 +342,8 @@
in_lock_tables(0),
bootstrap(0),
derived_tables_processing(FALSE),
- spcont(NULL)
+ spcont(NULL),
+ m_lip(NULL)
{
ulong tmp;
@@ -3026,9 +3061,9 @@
RETURN VALUE
Error code, or 0 if no error.
*/
-int THD::binlog_query(THD::enum_binlog_query_type qtype,
- char const *query, ulong query_len,
- bool is_trans, bool suppress_use)
+int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query,
+ ulong query_len, bool is_trans, bool suppress_use,
+ THD::killed_state killed_status_arg)
{
DBUG_ENTER("THD::binlog_query");
DBUG_PRINT("enter", ("qtype=%d, query='%s'", qtype, query));
@@ -3067,7 +3102,8 @@
flush the pending rows event if necessary.
*/
{
- Query_log_event qinfo(this, query, query_len, is_trans, suppress_use);
+ Query_log_event qinfo(this, query, query_len, is_trans, suppress_use,
+ killed_status_arg);
qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
/*
Binlog table maps will be irrelevant after a Query_log_event
--- 1.71/strings/ctype-ucs2.c 2007-05-29 09:31:46 +03:00
+++ 1.72/strings/ctype-ucs2.c 2007-06-21 10:42:08 +03:00
@@ -1487,7 +1487,10 @@
const uchar *pos = key;
key+= len;
-
+
+ while (key > pos+1 && key[-1] == ' ' && key[-2] == '\0')
+ key-= 2;
+
for (; pos < (uchar*) key ; pos++)
{
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
--- 1.68/sql/sql_plugin.cc 2007-05-29 16:47:09 +03:00
+++ 1.69/sql/sql_plugin.cc 2007-06-21 10:42:07 +03:00
@@ -210,6 +210,11 @@
/* declared in set_var.cc */
extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error);
+#ifdef EMBEDDED_LIBRARY
+/* declared in sql_base.cc */
+extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
+#endif /* EMBEDDED_LIBRARY */
+
/****************************************************************************
Value type thunks, allows the C world to play in the C++ world
@@ -278,7 +283,7 @@
DBUG_ENTER("plugin_dl_find");
for (i= 0; i < plugin_dl_array.elements; i++)
{
- tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *);
+ tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
if (tmp->ref_count &&
! my_strnncoll(files_charset_info,
(const uchar *)dl->str, dl->length,
@@ -296,17 +301,20 @@
DBUG_ENTER("plugin_dl_insert_or_reuse");
for (i= 0; i < plugin_dl_array.elements; i++)
{
- tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *);
+ tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
if (! tmp->ref_count)
{
memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl));
DBUG_RETURN(tmp);
}
}
- if (insert_dynamic(&plugin_dl_array, (uchar*)plugin_dl))
+ if (insert_dynamic(&plugin_dl_array, (uchar*)&plugin_dl))
DBUG_RETURN(0);
- DBUG_RETURN(dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
- struct st_plugin_dl *));
+ tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
+ struct st_plugin_dl **)=
+ (struct st_plugin_dl *) memdup_root(&plugin_mem_root, (uchar*)plugin_dl,
+ sizeof(struct st_plugin_dl));
+ DBUG_RETURN(tmp);
}
#endif /* HAVE_DLOPEN */
@@ -516,8 +524,8 @@
for (i= 0; i < plugin_dl_array.elements; i++)
{
- struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
- struct st_plugin_dl *);
+ struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i,
+ struct st_plugin_dl **);
if (tmp->ref_count &&
! my_strnncoll(files_charset_info,
(const uchar *)dl->str, dl->length,
@@ -665,21 +673,24 @@
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
{
uint i;
+ struct st_plugin_int *tmp;
DBUG_ENTER("plugin_insert_or_reuse");
for (i= 0; i < plugin_array.elements; i++)
{
- struct st_plugin_int *tmp= dynamic_element(&plugin_array, i,
- struct st_plugin_int *);
+ tmp= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
if (tmp->state == PLUGIN_IS_FREED)
{
memcpy(tmp, plugin, sizeof(struct st_plugin_int));
DBUG_RETURN(tmp);
}
}
- if (insert_dynamic(&plugin_array, (uchar*)plugin))
+ if (insert_dynamic(&plugin_array, (uchar*)&plugin))
DBUG_RETURN(0);
- DBUG_RETURN(dynamic_element(&plugin_array, plugin_array.elements - 1,
- struct st_plugin_int *));
+ tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
+ struct st_plugin_int **)=
+ (struct st_plugin_int *) memdup_root(&plugin_mem_root, (uchar*)plugin,
+ sizeof(struct st_plugin_int));
+ DBUG_RETURN(tmp);
}
@@ -873,7 +884,7 @@
for (idx= 0; idx < count; idx++)
{
- plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
+ plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count)
{
/* change the status flag to prevent reaping by another thread */
@@ -1096,9 +1107,9 @@
pthread_mutex_init(&LOCK_plugin, MY_MUTEX_INIT_FAST);
if (my_init_dynamic_array(&plugin_dl_array,
- sizeof(struct st_plugin_dl),16,16) ||
+ sizeof(struct st_plugin_dl *),16,16) ||
my_init_dynamic_array(&plugin_array,
- sizeof(struct st_plugin_int),16,16))
+ sizeof(struct st_plugin_int *),16,16))
goto err;
for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
@@ -1185,7 +1196,7 @@
for (i= 0; i < plugin_array.elements; i++)
{
- plugin_ptr= dynamic_element(&plugin_array, i, struct st_plugin_int *);
+ plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
{
if (plugin_initialize(plugin_ptr))
@@ -1233,11 +1244,13 @@
tmp->ref_count= 0;
tmp->plugin_dl= 0;
- if (insert_dynamic(&plugin_array, (uchar*)tmp))
+ if (insert_dynamic(&plugin_array, (uchar*)&tmp))
DBUG_RETURN(1);
- *ptr= dynamic_element(&plugin_array, plugin_array.elements - 1,
- struct st_plugin_int *);
+ *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1,
+ struct st_plugin_int **)=
+ (struct st_plugin_int *) memdup_root(&plugin_mem_root, (uchar*)tmp,
+ sizeof(struct st_plugin_int));
if (my_hash_insert(&plugin_hash[plugin->type],(uchar*) *ptr))
DBUG_RETURN(1);
@@ -1299,6 +1312,9 @@
READ_RECORD read_record_info;
int error;
THD *new_thd;
+#ifdef EMBEDDED_LIBRARY
+ bool table_exists;
+#endif /* EMBEDDED_LIBRARY */
DBUG_ENTER("plugin_load");
if (!(new_thd= new THD))
@@ -1315,6 +1331,20 @@
tables.alias= tables.table_name= (char*)"plugin";
tables.lock_type= TL_READ;
tables.db= new_thd->db;
+
+#ifdef EMBEDDED_LIBRARY
+ /*
+ When building an embedded library, if the mysql.plugin table
+ does not exist, we silently ignore the missing table
+ */
+ pthread_mutex_lock(&LOCK_open);
+ if (check_if_table_exists(new_thd, &tables, &table_exists))
+ table_exists= FALSE;
+ pthread_mutex_unlock(&LOCK_open);
+ if (!table_exists)
+ goto end;
+#endif /* EMBEDDED_LIBRARY */
+
if (simple_open_n_lock_tables(new_thd, &tables))
{
DBUG_PRINT("error",("Can't open plugin table"));
@@ -1459,7 +1489,7 @@
reap_plugins();
for (i= free_slots= 0; i < count; i++)
{
- plugin= dynamic_element(&plugin_array, i, struct st_plugin_int *);
+ plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
switch (plugin->state) {
case PLUGIN_IS_READY:
plugin->state= PLUGIN_IS_DELETED;
@@ -1491,7 +1521,7 @@
*/
for (i= 0; i < count; i++)
{
- plugins[i]= dynamic_element(&plugin_array, i, struct st_plugin_int *);
+ plugins[i]= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
/* change the state to ensure no reaping races */
if (plugins[i]->state == PLUGIN_IS_DELETED)
plugins[i]->state= PLUGIN_IS_DYING;
@@ -1556,7 +1586,7 @@
count= plugin_dl_array.elements;
dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count);
for (i= 0; i < count; i++)
- dl[i]= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *);
+ dl[i]= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
for (i= 0; i < plugin_dl_array.elements; i++)
free_plugin_mem(dl[i]);
my_afree(dl);
@@ -1715,7 +1745,7 @@
{
for (idx= 0; idx < total; idx++)
{
- plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
+ plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
}
}
@@ -3140,7 +3170,7 @@
if (initialized)
for (uint idx= 0; idx < plugin_array.elements; idx++)
{
- p= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
+ p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
if (!p->plugin->system_vars ||
!(opt= construct_help_options(&mem_root, p)))
--- 1.93/sql/ha_partition.cc 2007-05-29 19:46:45 +03:00
+++ 1.94/sql/ha_partition.cc 2007-06-21 10:42:06 +03:00
@@ -4253,22 +4253,16 @@
if (flag & HA_STATUS_AUTO)
{
- ulonglong nb_reserved_values;
+ ulonglong auto_increment_value= 0;
DBUG_PRINT("info", ("HA_STATUS_AUTO"));
- /* we don't want to reserve any values, it's pure information */
-
- if (table->found_next_number_field)
+ file_array= m_file;
+ do
{
- /*
- Can only call get_auto_increment for tables that actually
- have auto_increment columns, otherwise there will be
- problems in handlers that don't expect get_auto_increment
- for non-autoincrement tables.
- */
- get_auto_increment(0, 0, 0, &stats.auto_increment_value,
- &nb_reserved_values);
- release_auto_increment();
- }
+ file= *file_array;
+ file->info(HA_STATUS_AUTO);
+ set_if_bigger(auto_increment_value, file->stats.auto_increment_value);
+ } while (*(++file_array));
+ stats.auto_increment_value= auto_increment_value;
}
if (flag & HA_STATUS_VARIABLE)
{
--- 1.303/client/mysqltest.c 2007-05-29 09:31:46 +03:00
+++ 1.304/client/mysqltest.c 2007-06-21 10:42:05 +03:00
@@ -480,6 +480,10 @@
void handle_no_error(struct st_command*);
#ifdef EMBEDDED_LIBRARY
+
+/* attributes of the query thread */
+pthread_attr_t cn_thd_attrib;
+
/*
send_one_query executes query in separate thread what is
necessary in embedded library to run 'send' in proper way.
@@ -518,7 +522,7 @@
cn->cur_query= q;
cn->cur_query_len= q_len;
cn->query_done= 0;
- if (pthread_create(&tid, NULL, send_one_query, (void*)cn))
+ if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn))
die("Cannot start new thread for query");
return 0;
@@ -1127,6 +1131,50 @@
}
+/*
+ Remove surrounding chars from string
+
+ Return 1 if first character is found but not last
+*/
+static int strip_surrounding(char* str, char c1, char c2)
+{
+ char* ptr= str;
+
+ /* Check if the first non space character is c1 */
+ while(*ptr && my_isspace(charset_info, *ptr))
+ ptr++;
+ if (*ptr == c1)
+ {
+ /* Replace it with a space */
+ *ptr= ' ';
+
+ /* Last non space charecter should be c2 */
+ ptr= strend(str)-1;
+ while(*ptr && my_isspace(charset_info, *ptr))
+ ptr--;
+ if (*ptr == c2)
+ {
+ /* Replace it with \0 */
+ *ptr= 0;
+ }
+ else
+ {
+ /* Mismatch detected */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+static void strip_parentheses(struct st_command *command)
+{
+ if (strip_surrounding(command->first_argument, '(', ')'))
+ die("%.*s - argument list started with '%c' must be ended with '%c'",
+ command->first_word_len, command->query, '(', ')');
+}
+
+
static uchar *get_var_key(const uchar* var, size_t *len,
my_bool __attribute__((unused)) t)
{
@@ -1383,12 +1431,11 @@
init_dynamic_string(&ds_query, 0, (end - query) + 32, 256);
do_eval(&ds_query, query, end, FALSE);
- if (mysql_real_query(mysql, ds_query.str, ds_query.length) ||
- !(res = mysql_store_result(mysql)))
- {
+ if (mysql_real_query(mysql, ds_query.str, ds_query.length))
die("Error running query '%s': %d %s", ds_query.str,
mysql_errno(mysql), mysql_error(mysql));
- }
+ if (!(res= mysql_store_result(mysql)))
+ die("Query '%s' didn't return a result set", ds_query.str);
dynstr_free(&ds_query);
if ((row = mysql_fetch_row(res)) && row[0])
@@ -1442,6 +1489,130 @@
}
+/*
+ Set variable from the result of a field in a query
+
+ This function is useful when checking for a certain value
+ in the output from a query that can't be restricted to only
+ return some values. A very good example of that is most SHOW
+ commands.
+
+ SYNOPSIS
+ var_set_query_get_value()
+
+ DESCRIPTION
+ let $variable= query_get_value(<query to run>,<column name>,<row
no>);
+
+ <query to run> - The query that should be sent to the server
+ <column name> - Name of the column that holds the field be compared
+ against the expected value
+ <row no> - Number of the row that holds the field to be
+ compared against the expected value
+
+*/
+
+void var_set_query_get_value(struct st_command *command, VAR *var)
+{
+ ulong row_no;
+ int col_no= -1;
+ MYSQL_RES* res;
+ MYSQL* mysql= &cur_con->mysql;
+
+ static DYNAMIC_STRING ds_query;
+ static DYNAMIC_STRING ds_col;
+ static DYNAMIC_STRING ds_row;
+ const struct command_arg query_get_value_args[] = {
+ "query", ARG_STRING, TRUE, &ds_query, "Query to run",
+ "column name", ARG_STRING, TRUE, &ds_col, "Name of column",
+ "row number", ARG_STRING, TRUE, &ds_row, "Number for row",
+ };
+
+ DBUG_ENTER("var_set_query_get_value");
+ LINT_INIT(res);
+
+ strip_parentheses(command);
+ DBUG_PRINT("info", ("query: %s", command->query));
+ check_command_args(command, command->first_argument, query_get_value_args,
+ sizeof(query_get_value_args)/sizeof(struct command_arg),
+ ',');
+
+ DBUG_PRINT("info", ("query: %s", ds_query.str));
+ DBUG_PRINT("info", ("col: %s", ds_col.str));
+
+ /* Convert row number to int */
+ if (!str2int(ds_row.str, 10, (long) 0, (long) INT_MAX, &row_no))
+ die("Invalid row number: '%s'", ds_row.str);
+ DBUG_PRINT("info", ("row: %s, row_no: %ld", ds_row.str, row_no));
+ dynstr_free(&ds_row);
+
+ /* Remove any surrounding "'s from the query - if there is any */
+ if (strip_surrounding(ds_query.str, '"', '"'))
+ die("Mismatched \"'s around query '%s'", ds_query.str);
+
+ /* Run the query */
+ if (mysql_real_query(mysql, ds_query.str, ds_query.length))
+ die("Error running query '%s': %d %s", ds_query.str,
+ mysql_errno(mysql), mysql_error(mysql));
+ if (!(res= mysql_store_result(mysql)))
+ die("Query '%s' didn't return a result set", ds_query.str);
+
+ {
+ /* Find column number from the given column name */
+ uint i;
+ uint num_fields= mysql_num_fields(res);
+ MYSQL_FIELD *fields= mysql_fetch_fields(res);
+
+ for (i= 0; i < num_fields; i++)
+ {
+ if (strcmp(fields[i].name, ds_col.str) == 0 &&
+ strlen(fields[i].name) == ds_col.length)
+ {
+ col_no= i;
+ break;
+ }
+ }
+ if (col_no == -1)
+ {
+ mysql_free_result(res);
+ die("Could not find column '%s' in the result of '%s'",
+ ds_col.str, ds_query.str);
+ }
+ DBUG_PRINT("info", ("Found column %d with name '%s'",
+ i, fields[i].name));
+ }
+ dynstr_free(&ds_col);
+
+ {
+ /* Get the value */
+ MYSQL_ROW row;
+ ulong rows= 0;
+ const char* value= "No such row";
+
+ while ((row= mysql_fetch_row(res)))
+ {
+ if (++rows == row_no)
+ {
+
+ DBUG_PRINT("info", ("At row %ld, column %d is '%s'",
+ row_no, col_no, row[col_no]));
+ /* Found the row to get */
+ if (row[col_no])
+ value= row[col_no];
+ else
+ value= "NULL";
+
+ break;
+ }
+ }
+ eval_expr(var, value, 0);
+ }
+ dynstr_free(&ds_query);
+ mysql_free_result(res);
+
+ DBUG_VOID_RETURN;
+}
+
+
void var_copy(VAR *dest, VAR *src)
{
dest->int_val= src->int_val;
@@ -1465,26 +1636,47 @@
void eval_expr(VAR *v, const char *p, const char **p_end)
{
- static int MIN_VAR_ALLOC= 32; /* MASV why 32? */
- VAR *vp;
+
+ DBUG_ENTER("eval_expr");
+ DBUG_PRINT("enter", ("p: '%s'", p));
+
if (*p == '$')
{
+ VAR *vp;
if ((vp= var_get(p, p_end, 0, 0)))
- {
var_copy(v, vp);
- return;
- }
+ DBUG_VOID_RETURN;
}
- else if (*p == '`')
+
+ if (*p == '`')
{
var_query_set(v, p, p_end);
+ DBUG_VOID_RETURN;
}
- else
+
+ {
+ /* Check if this is a "let $var= query_get_value()" */
+ const char* get_value_str= "query_get_value";
+ const size_t len= strlen(get_value_str);
+ if (strncmp(p, get_value_str, len)==0)
+ {
+ struct st_command command;
+ memset(&command, 0, sizeof(command));
+ command.query= (char*)p;
+ command.first_word_len= len;
+ command.first_argument= command.query + len;
+ command.end= (char*)*p_end;
+ var_set_query_get_value(&command, v);
+ DBUG_VOID_RETURN;
+ }
+ }
+
{
int new_val_len = (p_end && *p_end) ?
(int) (*p_end - p) : (int) strlen(p);
if (new_val_len + 1 >= v->alloced_len)
{
+ static int MIN_VAR_ALLOC= 32;
v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
@@ -1497,9 +1689,10 @@
memcpy(v->str_val, p, new_val_len);
v->str_val[new_val_len] = 0;
v->int_val=atoi(p);
+ DBUG_PRINT("info", ("atoi on '%s', returns: %d", p, v->int_val));
v->int_dirty=0;
}
- return;
+ DBUG_VOID_RETURN;
}
@@ -3443,7 +3636,6 @@
int con_port= opt_port;
char *con_options;
bool con_ssl= 0, con_compress= 0;
- char *ptr;
static DYNAMIC_STRING ds_connection_name;
static DYNAMIC_STRING ds_host;
@@ -3467,20 +3659,7 @@
DBUG_ENTER("do_connect");
DBUG_PRINT("enter",("connect: %s", command->first_argument));
- /* Remove parenteses around connect arguments */
- if ((ptr= strstr(command->first_argument, "(")))
- {
- /* Replace it with a space */
- *ptr= ' ';
- if ((ptr= strstr(command->first_argument, ")")))
- {
- /* Replace it with \0 */
- *ptr= 0;
- }
- else
- die("connect - argument list started with '(' must be ended with ')'");
- }
-
+ strip_parentheses(command);
check_command_args(command, command->first_argument, connect_args,
sizeof(connect_args)/sizeof(struct command_arg),
',');
@@ -4178,16 +4357,12 @@
DBUG_RETURN(0);
}
if (!(*command_ptr= command=
- (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME))) ||
+ (struct st_command*) my_malloc(sizeof(*command),
+ MYF(MY_WME|MY_ZEROFILL))) ||
insert_dynamic(&q_lines, (uchar*) &command))
die(NullS);
-
- command->require_file[0]= 0;
- command->first_word_len= 0;
- command->query_len= 0;
-
command->type= Q_UNKNOWN;
- command->query_buf= command->query= 0;
+
read_command_buf[0]= 0;
if (read_line(read_command_buf, sizeof(read_command_buf)))
{
@@ -5984,6 +6159,12 @@
(sizeof(connections)/sizeof(struct st_connection)) - 1;
next_con= connections + 1;
cur_con= connections;
+
+#ifdef EMBEDDED_LIBRARY
+ /* set appropriate stack for the 'query' threads */
+ (void) pthread_attr_init(&cn_thd_attrib);
+ pthread_attr_setstacksize(&cn_thd_attrib, DEFAULT_THREAD_STACK);
+#endif /*EMBEDDED_LIBRARY*/
/* Init file stack */
memset(file_stack, 0, sizeof(file_stack));
--- 1.120/sql/ha_ndbcluster_binlog.cc 2007-05-29 16:47:09 +03:00
+++ 1.121/sql/ha_ndbcluster_binlog.cc 2007-06-21 10:42:06 +03:00
@@ -81,6 +81,20 @@
static Ndb *schema_ndb= 0;
static int ndbcluster_binlog_inited= 0;
+/*
+ Flag "ndbcluster_binlog_terminating" set when shutting down mysqld.
+ Server main loop should call handlerton function:
+
+ ndbcluster_hton->binlog_func ==
+ ndbcluster_binlog_func(...,BFN_BINLOG_END,...) ==
+ ndbcluster_binlog_end
+
+ at shutdown, which sets the flag. And then server needs to wait for it
+ to complete. Otherwise binlog will not be complete.
+
+ ndbcluster_hton->panic == ndbcluster_end() will not return until
+ ndb binlog is completed
+*/
static int ndbcluster_binlog_terminating= 0;
/*
@@ -222,7 +236,7 @@
- creating the ndb_apply_status table
*/
static void run_query(THD *thd, char *buf, char *end,
- my_bool print_error, my_bool disable_binlog)
+ const int *no_print_error, my_bool disable_binlog)
{
ulong save_query_length= thd->query_length;
char *save_query= thd->query;
@@ -242,11 +256,18 @@
DBUG_PRINT("query", ("%s", thd->query));
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
- if (print_error && thd->query_error)
+ if (no_print_error && thd->query_error)
{
- sql_print_error("NDB: %s: error %s %d %d %d",
- buf, thd->net.last_error, thd->net.last_errno,
- thd->net.report_error, thd->query_error);
+ int i;
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
+ for (i= 0; no_print_error[i]; i++)
+ if (thd_ndb->m_error == no_print_error[i])
+ break;
+ if (!no_print_error[i])
+ sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
+ buf, thd->net.last_error, thd->net.last_errno,
+ thd_ndb->m_error,
+ thd->net.report_error, thd->query_error);
}
thd->options= save_thd_options;
@@ -488,7 +509,7 @@
char buf[1024];
char *end= strmov(buf, "DELETE FROM " NDB_REP_DB "." NDB_REP_TABLE);
- run_query(thd, buf, end, FALSE, TRUE);
+ run_query(thd, buf, end, NULL, TRUE);
DBUG_RETURN(0);
}
@@ -513,7 +534,7 @@
NDB_REP_DB "." NDB_REP_TABLE
" WHERE File='"), file), "'");
- run_query(thd, buf, end, FALSE, TRUE);
+ run_query(thd, buf, end, NULL, TRUE);
DBUG_RETURN(0);
}
@@ -630,7 +651,7 @@
DBUG_ENTER("ndbcluster_reset_slave");
char buf[1024];
char *end= strmov(buf, "DELETE FROM " NDB_REP_DB "." NDB_APPLY_TABLE);
- run_query(thd, buf, end, FALSE, TRUE);
+ run_query(thd, buf, end, NULL, TRUE);
DBUG_VOID_RETURN;
}
@@ -755,7 +776,8 @@
" end_pos BIGINT UNSIGNED NOT NULL, "
" PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB");
- run_query(thd, buf, end, TRUE, TRUE);
+ const int no_print_error[2]= {701, 0}; // do not print error 701
+ run_query(thd, buf, end, no_print_error, TRUE);
DBUG_RETURN(0);
}
@@ -811,7 +833,8 @@
" type INT UNSIGNED NOT NULL,"
" PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB");
- run_query(thd, buf, end, TRUE, TRUE);
+ const int no_print_error[2]= {701, 0}; // do not print error 701
+ run_query(thd, buf, end, no_print_error, TRUE);
DBUG_RETURN(0);
}
@@ -1919,9 +1942,10 @@
/* Drop the database locally if it only contains ndb tables */
if (! ndbcluster_check_if_local_tables_in_db(thd, schema->db))
{
+ const int no_print_error[1]= {0};
run_query(thd, schema->query,
schema->query + schema->query_length,
- TRUE, /* print error */
+ no_print_error, /* print error */
TRUE); /* don't binlog the query */
/* binlog dropping database after any table operations */
post_epoch_log_list->push_back(schema, mem_root);
@@ -1941,12 +1965,15 @@
case SOT_CREATE_DB:
/* fall through */
case SOT_ALTER_DB:
+ {
+ const int no_print_error[1]= {0};
run_query(thd, schema->query,
schema->query + schema->query_length,
- TRUE, /* print error */
+ no_print_error, /* print error */
TRUE); /* don't binlog the query */
log_query= 1;
break;
+ }
case SOT_TABLESPACE:
case SOT_LOGFILE_GROUP:
log_query= 1;
| Thread |
|---|
| • bk commit into 5.1 tree (monty:1.2525) | monty | 21 Jun |