summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/examples/ha_tina.cc22
-rw-r--r--sql/field.cc4
-rw-r--r--sql/sql_parse.cc47
3 files changed, 50 insertions, 23 deletions
diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc
index 541e91f4b46..e00657c66ba 100644
--- a/sql/examples/ha_tina.cc
+++ b/sql/examples/ha_tina.cc
@@ -82,12 +82,16 @@ handlerton tina_hton= {
** TINA tables
*****************************************************************************/
-/*
- Used for sorting chains.
+/*
+ Used for sorting chains with qsort().
*/
int sort_set (tina_set *a, tina_set *b)
{
- return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) );
+ /*
+ We assume that intervals do not intersect. So, it is enought to compare
+ any two points. Here we take start of intervals for comparison.
+ */
+ return ( a->begin > b->begin ? -1 : ( a->begin < b->begin ? 1 : 0 ) );
}
static byte* tina_get_key(TINA_SHARE *share,uint *length,
@@ -186,7 +190,8 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table)
thr_lock_init(&share->lock);
pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
- if ((share->data_file= my_open(data_file_name, O_RDWR, MYF(0))) == -1)
+ if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND,
+ MYF(0))) == -1)
goto error2;
/* We only use share->data_file for writing, so we scan to the end to append */
@@ -797,13 +802,8 @@ int ha_tina::rnd_end()
qsort(chain, (size_t)(chain_ptr - chain), sizeof(tina_set), (qsort_cmp)sort_set);
for (ptr= chain; ptr < chain_ptr; ptr++)
{
- /* We peek a head to see if this is the last chain */
- if (ptr+1 == chain_ptr)
- memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end,
- length - (size_t)ptr->end);
- else
- memmove((caddr_t)share->mapped_file + ptr->begin, (caddr_t)share->mapped_file + ptr->end,
- (size_t)((ptr++)->begin - ptr->end));
+ memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end,
+ length - (size_t)ptr->end);
length= length - (size_t)(ptr->end - ptr->begin);
}
diff --git a/sql/field.cc b/sql/field.cc
index f7f7c22bfe9..381a13c3263 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -7938,7 +7938,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
{
int delta;
- for (; !*from && length; from++, length--); // skip left 0's
+ for (; length && !*from; from++, length--); // skip left 0's
delta= field_length - length;
if (delta < -1 ||
@@ -8158,7 +8158,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
int delta;
uchar bits= create_length & 7;
- for (; !*from && length; from++, length--); // skip left 0's
+ for (; length && !*from; from++, length--); // skip left 0's
delta= field_length - length;
if (delta < 0 ||
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index aab4caec5d4..4bbca55f6ba 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -194,6 +194,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
#endif
+static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
+{
+ for (TABLE_LIST *table= tables; table; table= table->next_global)
+ {
+ DBUG_ASSERT(table->db && table->table_name);
+ if (table->updating &&
+ !find_temporary_table(thd, table->db, table->table_name))
+ return 1;
+ }
+ return 0;
+}
+
static HASH hash_user_connections;
static int get_or_create_user_conn(THD *thd, const char *user,
@@ -2365,7 +2377,7 @@ mysql_execute_command(THD *thd)
mysql_reset_errors(thd, 0);
#ifdef HAVE_REPLICATION
- if (thd->slave_thread)
+ if (unlikely(thd->slave_thread))
{
/*
Check if statment should be skipped because of slave filtering
@@ -2404,16 +2416,20 @@ mysql_execute_command(THD *thd)
}
#endif
}
+ else
#endif /* HAVE_REPLICATION */
/*
- When option readonly is set deny operations which change tables.
- Except for the replication thread and the 'super' users.
+ When option readonly is set deny operations which change non-temporary
+ tables. Except for the replication thread and the 'super' users.
*/
if (opt_readonly &&
- !(thd->slave_thread ||
- (thd->security_ctx->master_access & SUPER_ACL)) &&
- uc_update_queries[lex->sql_command])
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ uc_update_queries[lex->sql_command] &&
+ !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
+ (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
+ ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
+ some_non_temp_table_to_be_updated(thd, all_tables)))
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(-1);
@@ -3212,13 +3228,24 @@ end_with_restore_list:
#ifdef HAVE_REPLICATION
/* Check slave filtering rules */
- if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
+ if (unlikely(thd->slave_thread))
{
- /* we warn the slave SQL thread */
- my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
- break;
+ if (all_tables_not_ok(thd, all_tables))
+ {
+ /* we warn the slave SQL thread */
+ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
+ break;
+ }
}
+ else
#endif /* HAVE_REPLICATION */
+ if (opt_readonly &&
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ some_non_temp_table_to_be_updated(thd, all_tables))
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+ break;
+ }
res= mysql_multi_update(thd, all_tables,
&select_lex->item_list,