different users of run_query do different things...
none just resets the diag area, they first look and see if there is an
error that should be propagated...
T
On Wed, 2008-12-10 at 19:51 +0300, Konstantin Osipov wrote:
> * Tomas Ulin <Tomas.Ulin@stripped> [08/12/10 16:36]:
> > 2691 Tomas Ulin 2008-12-10 [merge]
> > merge and use new Ed_connection in run_query
> > modified:
> > sql/ha_ndbcluster_binlog.cc
>
> BTW, what's the point of propagating the error message to the thd
> diagnostics are only to have to clear it later by calling
> reset_diagnostics_area()? Or I am missing something?
>
> > === modified file 'sql/ha_ndbcluster_binlog.cc'
> > --- a/sql/ha_ndbcluster_binlog.cc 2008-12-09 18:59:54 +0000
> > +++ b/sql/ha_ndbcluster_binlog.cc 2008-12-10 13:28:23 +0000
> > @@ -24,6 +24,7 @@
> > #include "rpl_injector.h"
> > #include "rpl_filter.h"
> > #include "slave.h"
> > +#include "sql_prepare.h"
> > #include "ha_ndbcluster_binlog.h"
> > #include <ndbapi/NdbDictionary.hpp>
> > #include <ndbapi/ndb_cluster_connection.hpp>
> > @@ -245,78 +246,58 @@ static void dbug_print_table(const char
> > - purging the ndb_binlog_index
> > - creating the ndb_apply_status table
> > */
> > +static void copy_warnings(THD *thd, List<MYSQL_ERROR> *src)
> > +{
> > + List_iterator_fast<MYSQL_ERROR> err_it(*src);
> > + MYSQL_ERROR *err;
> > +
> > + while ((err= err_it++))
> > + push_warning(thd, err->level, err->code, err->msg);
> > +}
> > static void run_query(THD *thd, char *buf, char *end,
> > - const int *no_print_error, my_bool disable_binlog)
> > + const int *no_print_error, my_bool disable_binlog,
> > + my_bool reset_error)
> > {
> > - ulong save_thd_query_length= thd->query_length;
> > - char *save_thd_query= thd->query;
> > - ulong save_thread_id= thd->variables.pseudo_thread_id;
> > - struct system_status_var save_thd_status_var= thd->status_var;
> > - THD_TRANS save_thd_transaction_all= thd->transaction.all;
> > - THD_TRANS save_thd_transaction_stmt= thd->transaction.stmt;
> > ulonglong save_thd_options= thd->options;
> > DBUG_ASSERT(sizeof(save_thd_options) == sizeof(thd->options));
> > - NET save_thd_net= thd->net;
> > - const char* found_semicolon= NULL;
> >
> > - bzero((char*) &thd->net, sizeof(NET));
> > - thd->query_length= end - buf;
> > - thd->query= buf;
> > - thd->variables.pseudo_thread_id= thread_id;
> > - thd->transaction.stmt.modified_non_trans_table= FALSE;
> > + LEX_STRING query= {buf, end - buf};
> > if (disable_binlog)
> > thd->options&= ~OPTION_BIN_LOG;
> > -
> > - DBUG_PRINT("query", ("%s", thd->query));
> > +
> > + DBUG_PRINT("query", ("%s", query.str));
> >
> > DBUG_ASSERT(!thd->in_sub_stmt);
> > DBUG_ASSERT(!thd->locked_tables_mode);
> >
> > - mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
> > -
> > - if (no_print_error && thd->is_slave_error)
> > {
> > - int i;
> > - Thd_ndb *thd_ndb= get_thd_ndb(thd);
> > - for (i= 0; no_print_error[i]; i++)
> > - if ((thd_ndb->m_error_code == no_print_error[i]) ||
> > - (thd->stmt_da->sql_errno() == (unsigned) no_print_error[i]))
> > - break;
> > - if (!no_print_error[i])
> > - sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
> > - buf,
> > - thd->stmt_da->message(),
> > - thd->stmt_da->sql_errno(),
> > - thd_ndb->m_error_code,
> > - (int) thd->is_error(), thd->is_slave_error);
> > - }
> > + Ed_connection con(thd);
> > + bool res= con.execute_direct(query);
> >
> > - /*
> > - After executing statement we should unlock and close tables open
> > - by it as well as release meta-data locks obtained by it.
> > - */
> > - close_thread_tables(thd);
> > + if (no_print_error && res)
> > + {
> > + int i;
> > + Thd_ndb *thd_ndb= get_thd_ndb(thd);
> > + for (i= 0; no_print_error[i]; i++)
> > + if ((thd_ndb->m_error_code == no_print_error[i]) ||
> > + (con.get_last_errno() == (unsigned)no_print_error[i]))
> > + break;
> > + if (!no_print_error[i])
> > + sql_print_error("NDB: %s: error %s %d(ndb: %d)",
> > + buf,
> > + con.get_last_error(),
> > + con.get_last_errno(),
> > + thd_ndb->m_error_code);
> > + }
> >
> > - /*
> > - XXX: this code is broken. mysql_parse()/mysql_reset_thd_for_next_command()
> > - can not be called from within a statement, and
> > - run_query() can be called from anywhere, including from within
> > - a sub-statement.
> > - This particular reset is a temporary hack to avoid an assert
> > - for double assignment of the diagnostics area when run_query()
> > - is called from ndbcluster_reset_logs(), which is called from
> > - mysql_flush().
> > - */
> > - thd->stmt_da->reset_diagnostics_area();
> > + if (res && !reset_error)
> > + {
> > + copy_warnings(thd, con.get_warn_list());
> > + my_message(con.get_last_errno(), con.get_last_error(),
> MYF(ME_NO_WARNING_FOR_ERROR));
> > + }
> > + }
> >
> > thd->options= save_thd_options;
> > - thd->query_length= save_thd_query_length;
> > - thd->query= save_thd_query;
> > - thd->variables.pseudo_thread_id= save_thread_id;
> > - thd->status_var= save_thd_status_var;
> > - thd->transaction.all= save_thd_transaction_all;
> > - thd->transaction.stmt= save_thd_transaction_stmt;
> > - thd->net= save_thd_net;
> > }
> >
> > static void
> > @@ -531,7 +512,26 @@ static int ndbcluster_reset_logs(THD *th
> > char buf[1024];
> > char *end= strmov(buf, "TRUNCATE " NDB_REP_DB "." NDB_REP_TABLE);
> >
> > - run_query(thd, buf, end, NULL, TRUE);
> > + run_query(thd, buf, end, NULL, TRUE, FALSE);
> > +
> > + /*
> > + Calling function only expects and handles error cases,
> > + so reset state if not an error as not to hit asserts
> > + in upper layers
> > + */
> > + while (thd->stmt_da->is_error())
> > + {
> > + if (thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
> > + {
> > + /*
> > + If table does not exist ignore the error as it
> > + is a consistant behavior
> > + */
> > + break;
> > + }
> > + DBUG_RETURN(1);
> > + }
> > + thd->stmt_da->reset_diagnostics_area();
> >
> > DBUG_RETURN(0);
> > }
> > @@ -556,7 +556,16 @@ ndbcluster_binlog_index_purge_file(THD *
> > NDB_REP_DB "." NDB_REP_TABLE
> > " WHERE File='"), file), "'");
> >
> > - run_query(thd, buf, end, NULL, TRUE);
> > + run_query(thd, buf, end, NULL, TRUE, FALSE);
> > + if (thd->stmt_da->is_error() &&
> > + thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
> > + {
> > + /*
> > + If table does not exist ignore the error as it
> > + is a consistant behavior
> > + */
> > + thd->stmt_da->reset_diagnostics_area();
> > + }
> >
> > DBUG_RETURN(0);
> > }
> > @@ -673,16 +682,16 @@ static void ndbcluster_reset_slave(THD *
> > 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, NULL, TRUE);
> > - if (thd->main_da.is_error() &&
> > - ((thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) ||
> > - (thd->main_da.sql_errno() == ER_OPEN_AS_READONLY &&
> ndbcluster_silent)))
> > + run_query(thd, buf, end, NULL, TRUE, FALSE);
> > + if (thd->stmt_da->is_error() &&
> > + ((thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) ||
> > + (thd->stmt_da->sql_errno() == ER_OPEN_AS_READONLY &&
> ndbcluster_silent)))
> > {
> > /*
> > If table does not exist ignore the error as it
> > is a consistant behavior
> > */
> > - thd->main_da.reset_diagnostics_area();
> > + thd->stmt_da->reset_diagnostics_area();
> > /*
> > ndbcluster_silent
> > - avoid "no table mysql.ndb_apply_status" warning - ER_NO_SUCH_TABLE
> > @@ -1052,7 +1061,7 @@ static int ndbcluster_create_ndb_apply_s
> >
> > end= strmov(buf, "FLUSH TABLE " NDB_REP_DB "." NDB_APPLY_TABLE);
> > const int no_print_error[1]= {0};
> > - run_query(thd, buf, end, no_print_error, TRUE);
> > + run_query(thd, buf, end, no_print_error, TRUE, TRUE);
> > }
> > }
> >
> > @@ -1074,7 +1083,7 @@ static int ndbcluster_create_ndb_apply_s
> > 721, // Table already exist
> > 4009,
> > 0}; // do not print error 701 etc
> > - run_query(thd, buf, end, no_print_error, TRUE);
> > + run_query(thd, buf, end, no_print_error, TRUE, TRUE);
> >
> > DBUG_RETURN(0);
> > }
> > @@ -1125,7 +1134,7 @@ static int ndbcluster_create_schema_tabl
> >
> > end= strmov(buf, "FLUSH TABLE " NDB_REP_DB "." NDB_SCHEMA_TABLE);
> > const int no_print_error[1]= {0};
> > - run_query(thd, buf, end, no_print_error, TRUE);
> > + run_query(thd, buf, end, no_print_error, TRUE, TRUE);
> > }
> > }
> >
> > @@ -1151,7 +1160,7 @@ static int ndbcluster_create_schema_tabl
> > 721, // Table already exist
> > 4009,
> > 0}; // do not print error 701 etc
> > - run_query(thd, buf, end, no_print_error, TRUE);
> > + run_query(thd, buf, end, no_print_error, TRUE, TRUE);
> >
> > DBUG_RETURN(0);
> > }
> > @@ -1268,9 +1277,8 @@ static int ndbcluster_find_all_databases
> > const int no_print_error[1]= {0};
> > run_query(thd, query, query + query_length,
> > no_print_error, /* print error */
> > - TRUE); /* don't binlog the query */
> > - /* always reset here */
> > - thd->main_da.reset_diagnostics_area();
> > + TRUE, /* don't binlog the query */
> > + TRUE); /* reset error */
> > }
> > }
> > else if (strncasecmp("ALTER", query, 5) == 0)
> > @@ -1284,13 +1292,12 @@ static int ndbcluster_find_all_databases
> > name_len= my_snprintf(name, sizeof(name), "CREATE DATABASE %s",
> db);
> > run_query(thd, name, name + name_len,
> > no_print_error, /* print error */
> > - TRUE); /* don't binlog the query */
> > - thd->main_da.reset_diagnostics_area();
> > + TRUE, /* don't binlog the query */
> > + TRUE); /* reset error */
> > run_query(thd, query, query + query_length,
> > no_print_error, /* print error */
> > - TRUE); /* don't binlog the query */
> > - /* always reset here */
> > - thd->main_da.reset_diagnostics_area();
> > + TRUE, /* don't binlog the query */
> > + TRUE); /* reset error */
> > }
> > }
> > else if (strncasecmp("DROP", query, 4) == 0)
> > @@ -2330,13 +2337,13 @@ ndb_binlog_thread_handle_schema_event(TH
> > if (! ndbcluster_check_if_local_table(schema->db,
> schema->name))
> > {
> > thd_ndb_options.set(TNO_NO_LOCK_SCHEMA_OP);
> > - const int no_print_error[1]=
> > - {ER_BAD_TABLE_ERROR}; /* ignore missing table */
> > + const int no_print_error[2]=
> > + {ER_BAD_TABLE_ERROR, 0}; /* ignore missing table */
> > run_query(thd, schema->query,
> > schema->query + schema->query_length,
> > no_print_error, // /* don't print error */
> > - TRUE); // /* don't binlog the query */
> > -
> > + TRUE, /* don't binlog the query */
> > + TRUE); /* reset error */
> > /* binlog dropping table after any table operations */
> > post_epoch_log_list->push_back(schema, mem_root);
> > /* acknowledge this query _after_ epoch completion */
> > @@ -2424,7 +2431,8 @@ ndb_binlog_thread_handle_schema_event(TH
> > run_query(thd, schema->query,
> > schema->query + schema->query_length,
> > no_print_error, /* print error */
> > - TRUE); /* don't binlog the query */
> > + TRUE, /* don't binlog the query */
> > + TRUE); /* reset error */
> > /* binlog dropping database after any table operations */
> > post_epoch_log_list->push_back(schema, mem_root);
> > /* acknowledge this query _after_ epoch completion */
> > @@ -2452,7 +2460,8 @@ ndb_binlog_thread_handle_schema_event(TH
> > run_query(thd, schema->query,
> > schema->query + schema->query_length,
> > no_print_error, /* print error */
> > - TRUE); /* don't binlog the query */
> > + TRUE, /* don't binlog the query */
> > + TRUE); /* reset error */
> > log_query= 1;
> > break;
> > }
>