summaryrefslogtreecommitdiff
path: root/sql/ha_federated.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_federated.cc')
-rw-r--r--sql/ha_federated.cc275
1 files changed, 152 insertions, 123 deletions
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index f4fc5f47193..1471b25f7b6 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -364,7 +364,8 @@ pthread_mutex_t federated_mutex; // To init the hash
static int federated_init= FALSE; // Checking the state of hash
/* Static declaration for handerton */
-static handler *federated_create_handler(TABLE_SHARE *table);
+static handler *federated_create_handler(TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
static int federated_commit(THD *thd, bool all);
static int federated_rollback(THD *thd, bool all);
@@ -412,9 +413,10 @@ handlerton federated_hton= {
};
-static handler *federated_create_handler(TABLE_SHARE *table)
+static handler *federated_create_handler(TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
{
- return new ha_federated(table);
+ return new (mem_root) ha_federated(table);
}
@@ -796,6 +798,7 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
{
ulong *lengths;
Field **field;
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
DBUG_ENTER("ha_federated::convert_row_to_internal_format");
lengths= mysql_fetch_lengths(stored_result);
@@ -814,12 +817,15 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
(*field)->set_null();
else
{
- (*field)->set_notnull();
- (*field)->store(*row, *lengths, &my_charset_bin);
+ if (bitmap_is_set(table->read_set, (*field)->field_index))
+ {
+ (*field)->set_notnull();
+ (*field)->store(*row, *lengths, &my_charset_bin);
+ }
}
(*field)->move_field_offset(-old_ptr);
}
-
+ dbug_tmp_restore_column_map(table->write_set, old_map);
DBUG_RETURN(0);
}
@@ -1138,22 +1144,25 @@ bool ha_federated::create_where_from_key(String *to,
KEY *key_info,
const key_range *start_key,
const key_range *end_key,
- bool records_in_range)
+ bool records_in_range,
+ bool eq_range)
{
- bool both_not_null=
+ bool both_not_null=
(start_key != NULL && end_key != NULL) ? TRUE : FALSE;
const byte *ptr;
uint remainder, length;
char tmpbuff[FEDERATED_QUERY_BUFFER_SIZE];
String tmp(tmpbuff, sizeof(tmpbuff), system_charset_info);
const key_range *ranges[2]= { start_key, end_key };
+ my_bitmap_map *old_map;
DBUG_ENTER("ha_federated::create_where_from_key");
tmp.length(0);
if (start_key == NULL && end_key == NULL)
DBUG_RETURN(1);
- for (int i= 0; i <= 1; i++)
+ old_map= dbug_tmp_use_all_columns(table, table->write_set);
+ for (uint i= 0; i <= 1; i++)
{
bool needs_quotes;
KEY_PART_INFO *key_part;
@@ -1187,16 +1196,16 @@ bool ha_federated::create_where_from_key(String *to,
{
if (emit_key_part_name(&tmp, key_part) ||
tmp.append(FEDERATED_ISNULL))
- DBUG_RETURN(1);
+ goto err;
continue;
}
}
if (tmp.append(FEDERATED_OPENPAREN))
- DBUG_RETURN(1);
+ goto err;
- switch(ranges[i]->flag) {
- case(HA_READ_KEY_EXACT):
+ switch (ranges[i]->flag) {
+ case HA_READ_KEY_EXACT:
DBUG_PRINT("info", ("federated HA_READ_KEY_EXACT %d", i));
if (store_length >= length ||
!needs_quotes ||
@@ -1204,22 +1213,22 @@ bool ha_federated::create_where_from_key(String *to,
field->result_type() != STRING_RESULT)
{
if (emit_key_part_name(&tmp, key_part))
- DBUG_RETURN(1);
+ goto err;
if (records_in_range)
{
if (tmp.append(FEDERATED_GE))
- DBUG_RETURN(1);
+ goto err;
}
else
{
if (tmp.append(FEDERATED_EQ))
- DBUG_RETURN(1);
+ goto err;
}
if (emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
- DBUG_RETURN(1);
+ goto err;
}
else
{
@@ -1228,43 +1237,49 @@ bool ha_federated::create_where_from_key(String *to,
tmp.append(FEDERATED_LIKE) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 1, ptr,
part_length))
- DBUG_RETURN(1);
+ goto err;
}
break;
- case(HA_READ_AFTER_KEY):
+ case HA_READ_AFTER_KEY:
+ if (eq_range)
+ {
+ if (tmp.append("1=1")) // Dummy
+ goto err;
+ break;
+ }
DBUG_PRINT("info", ("federated HA_READ_AFTER_KEY %d", i));
if (store_length >= length) /* end key */
{
if (emit_key_part_name(&tmp, key_part))
- DBUG_RETURN(1);
+ goto err;
if (i > 0) /* end key */
{
if (tmp.append(FEDERATED_LE))
- DBUG_RETURN(1);
+ goto err;
}
else /* start key */
{
if (tmp.append(FEDERATED_GT))
- DBUG_RETURN(1);
+ goto err;
}
if (emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
{
- DBUG_RETURN(1);
+ goto err;
}
break;
}
- case(HA_READ_KEY_OR_NEXT):
+ case HA_READ_KEY_OR_NEXT:
DBUG_PRINT("info", ("federated HA_READ_KEY_OR_NEXT %d", i));
if (emit_key_part_name(&tmp, key_part) ||
tmp.append(FEDERATED_GE) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
- DBUG_RETURN(1);
+ goto err;
break;
- case(HA_READ_BEFORE_KEY):
+ case HA_READ_BEFORE_KEY:
DBUG_PRINT("info", ("federated HA_READ_BEFORE_KEY %d", i));
if (store_length >= length)
{
@@ -1272,23 +1287,23 @@ bool ha_federated::create_where_from_key(String *to,
tmp.append(FEDERATED_LT) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
- DBUG_RETURN(1);
+ goto err;
break;
}
- case(HA_READ_KEY_OR_PREV):
+ case HA_READ_KEY_OR_PREV:
DBUG_PRINT("info", ("federated HA_READ_KEY_OR_PREV %d", i));
if (emit_key_part_name(&tmp, key_part) ||
tmp.append(FEDERATED_LE) ||
emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
- DBUG_RETURN(1);
+ goto err;
break;
default:
DBUG_PRINT("info",("cannot handle flag %d", ranges[i]->flag));
- DBUG_RETURN(1);
+ goto err;
}
if (tmp.append(FEDERATED_CLOSEPAREN))
- DBUG_RETURN(1);
+ goto err;
next_loop:
if (store_length >= length)
@@ -1298,13 +1313,15 @@ next_loop:
length-= store_length;
ptr+= store_length;
if (tmp.append(FEDERATED_AND))
- DBUG_RETURN(1);
+ goto err;
DBUG_PRINT("info",
("create_where_from_key WHERE clause: %s",
tmp.c_ptr_quick()));
}
}
+ dbug_tmp_restore_column_map(table->write_set, old_map);
+
if (both_not_null)
if (tmp.append(FEDERATED_CLOSEPAREN))
DBUG_RETURN(1);
@@ -1316,6 +1333,10 @@ next_loop:
DBUG_RETURN(1);
DBUG_RETURN(0);
+
+err:
+ dbug_tmp_restore_column_map(table->write_set, old_map);
+ DBUG_RETURN(1);
}
/*
@@ -1355,7 +1376,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
query.append(FEDERATED_BTICK);
query.append(FEDERATED_COMMA);
}
- query.length(query.length()- (FEDERATED_COMMA_LEN - 1));
+ query.length(query.length()- FEDERATED_COMMA_LEN);
query.append(FEDERATED_FROM);
query.append(FEDERATED_BTICK);
@@ -1606,15 +1627,16 @@ int ha_federated::write_row(byte *buf)
String insert_field_value_string(insert_field_value_buffer,
sizeof(insert_field_value_buffer),
&my_charset_bin);
- values_string.length(0);
- insert_string.length(0);
- insert_field_value_string.length(0);
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
DBUG_ENTER("ha_federated::write_row");
DBUG_PRINT("info",
("table charset name %s csname %s",
table->s->table_charset->name,
table->s->table_charset->csname));
+ values_string.length(0);
+ insert_string.length(0);
+ insert_field_value_string.length(0);
statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
@@ -1641,7 +1663,7 @@ int ha_federated::write_row(byte *buf)
for (field= table->field; *field; field++)
{
/* if there is a query id and if it's equal to the current query id */
- if (ha_get_bit_in_write_set((*field)->fieldnr))
+ if (bitmap_is_set(table->write_set, (*field)->field_index))
{
/*
There are some fields. This will be used later to determine
@@ -1666,22 +1688,17 @@ int ha_federated::write_row(byte *buf)
/* append commas between both fields and fieldnames */
/*
- unfortunately, we can't use the logic
- if *(fields + 1) to make the following
- appends conditional because we may not append
- if the next field doesn't match the condition:
- (((*field)->query_id && (*field)->query_id == current_query_id)
+ unfortunately, we can't use the logic if *(fields + 1) to
+ make the following appends conditional as we don't know if the
+ next field is in the write set
*/
insert_string.append(FEDERATED_COMMA);
values_string.append(FEDERATED_COMMA);
}
}
+ dbug_tmp_restore_column_map(table->read_set, old_map);
/*
- remove trailing comma
- */
- insert_string.length(insert_string.length() - strlen(FEDERATED_COMMA));
- /*
if there were no fields, we don't want to add a closing paren
AND, we don't want to chop off the last char '('
insert will be "INSERT INTO t1 VALUES ();"
@@ -1689,9 +1706,13 @@ int ha_federated::write_row(byte *buf)
if (has_fields)
{
/* chops off leading commas */
- values_string.length(values_string.length() - strlen(FEDERATED_COMMA));
+ insert_string.length(insert_string.length() - FEDERATED_COMMA_LEN);
+ values_string.length(values_string.length() - FEDERATED_COMMA_LEN);
insert_string.append(FEDERATED_CLOSEPAREN);
}
+ else
+ insert_string.length(insert_string.length() - FEDERATED_CLOSEPAREN_LEN);
+
/* we always want to append this, even if there aren't any fields */
values_string.append(FEDERATED_CLOSEPAREN);
@@ -1705,8 +1726,8 @@ int ha_federated::write_row(byte *buf)
DBUG_RETURN(stash_remote_error());
}
/*
- If the table we've just written a record to contains an auto_increment field,
- then store the last_insert_id() value from the foreign server
+ If the table we've just written a record to contains an auto_increment
+ field, then store the last_insert_id() value from the foreign server
*/
if (table->next_number_field)
update_auto_increment();
@@ -1728,7 +1749,7 @@ void ha_federated::update_auto_increment(void)
DBUG_ENTER("ha_federated::update_auto_increment");
thd->insert_id(mysql->last_used_con->insert_id);
- DBUG_PRINT("info",("last_insert_id %d", auto_increment_value));
+ DBUG_PRINT("info",("last_insert_id %d", stats.auto_increment_value));
DBUG_VOID_RETURN;
}
@@ -1816,7 +1837,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
this? Because we only are updating one record, and LIMIT enforces
this.
*/
- bool has_a_primary_key= (table->s->primary_key == 0 ? TRUE : FALSE);
+ bool has_a_primary_key= test(table->s->primary_key != MAX_KEY);
/*
buffers for following strings
*/
@@ -1868,48 +1889,52 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
for (Field **field= table->field; *field; field++)
{
- where_string.append((*field)->field_name);
- update_string.append((*field)->field_name);
- update_string.append(FEDERATED_EQ);
-
- if ((*field)->is_null())
- new_field_value.append(FEDERATED_NULL);
- else
+ if (bitmap_is_set(table->write_set, (*field)->field_index))
{
- /* otherwise = */
- (*field)->val_str(&new_field_value);
- (*field)->quote_data(&new_field_value);
-
- if (!field_in_record_is_null(table, *field, (char*) old_data))
- where_string.append(FEDERATED_EQ);
- }
-
- if (field_in_record_is_null(table, *field, (char*) old_data))
- where_string.append(FEDERATED_ISNULL);
- else
- {
- (*field)->val_str(&old_field_value,
- (char*) (old_data + (*field)->offset()));
- (*field)->quote_data(&old_field_value);
- where_string.append(old_field_value);
+ if ((*field)->is_null())
+ new_field_value.append(FEDERATED_NULL);
+ else
+ {
+ my_bitmap_map *old_map= tmp_use_all_columns(table, table->read_set);
+ /* otherwise = */
+ (*field)->val_str(&new_field_value);
+ (*field)->quote_data(&new_field_value);
+ tmp_restore_column_map(table->read_set, old_map);
+ }
+ update_string.append((*field)->field_name);
+ update_string.append(FEDERATED_EQ);
+ update_string.append(new_field_value);
+ update_string.append(FEDERATED_COMMA);
+ new_field_value.length(0);
}
- update_string.append(new_field_value);
- new_field_value.length(0);
-
- /*
- Only append conjunctions if we have another field in which
- to iterate
- */
- if (*(field + 1))
+ if (bitmap_is_set(table->read_set, (*field)->field_index))
{
- update_string.append(FEDERATED_COMMA);
+ where_string.append((*field)->field_name);
+ if (field_in_record_is_null(table, *field, (char*) old_data))
+ where_string.append(FEDERATED_ISNULL);
+ else
+ {
+ where_string.append(FEDERATED_EQ);
+ (*field)->val_str(&old_field_value,
+ (char*) (old_data + (*field)->offset()));
+ (*field)->quote_data(&old_field_value);
+ where_string.append(old_field_value);
+ old_field_value.length(0);
+ }
where_string.append(FEDERATED_AND);
}
- old_field_value.length(0);
}
- update_string.append(FEDERATED_WHERE);
- update_string.append(where_string);
+
+ /* Remove last ', '. This works as there must be at least on updated field */
+ update_string.length(update_string.length() - FEDERATED_COMMA_LEN);
+ if (where_string.length())
+ {
+ where_string.length(where_string.length() - FEDERATED_AND_LEN);
+ update_string.append(FEDERATED_WHERE);
+ update_string.append(where_string);
+ }
+
/*
If this table has not a primary key, then we could possibly
update multiple rows. We want to make sure to only update one!
@@ -1943,9 +1968,9 @@ int ha_federated::delete_row(const byte *buf)
{
char delete_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char data_buffer[FEDERATED_QUERY_BUFFER_SIZE];
-
String delete_string(delete_buffer, sizeof(delete_buffer), &my_charset_bin);
String data_string(data_buffer, sizeof(data_buffer), &my_charset_bin);
+ uint found= 0;
DBUG_ENTER("ha_federated::delete_row");
delete_string.length(0);
@@ -1959,25 +1984,31 @@ int ha_federated::delete_row(const byte *buf)
for (Field **field= table->field; *field; field++)
{
Field *cur_field= *field;
- data_string.length(0);
- delete_string.append(cur_field->field_name);
-
- if (cur_field->is_null())
- {
- delete_string.append(FEDERATED_IS);
- data_string.append(FEDERATED_NULL);
- }
- else
+ found++;
+ if (bitmap_is_set(table->read_set, cur_field->field_index))
{
- delete_string.append(FEDERATED_EQ);
- cur_field->val_str(&data_string);
- cur_field->quote_data(&data_string);
+ data_string.length(0);
+ delete_string.append(cur_field->field_name);
+ if (cur_field->is_null())
+ {
+ delete_string.append(FEDERATED_IS);
+ delete_string.append(FEDERATED_NULL);
+ }
+ else
+ {
+ delete_string.append(FEDERATED_EQ);
+ cur_field->val_str(&data_string);
+ cur_field->quote_data(&data_string);
+ delete_string.append(data_string);
+ }
+ delete_string.append(FEDERATED_AND);
}
-
- delete_string.append(data_string);
- delete_string.append(FEDERATED_AND);
}
- delete_string.length(delete_string.length()-5); // Remove trailing AND
+
+ // Remove trailing AND
+ delete_string.length(delete_string.length() - FEDERATED_AND_LEN);
+ if (!found)
+ delete_string.length(delete_string.length() - FEDERATED_WHERE_LEN);
delete_string.append(FEDERATED_LIMIT1);
DBUG_PRINT("info",
@@ -1986,10 +2017,10 @@ int ha_federated::delete_row(const byte *buf)
{
DBUG_RETURN(stash_remote_error());
}
- deleted+= mysql->affected_rows;
+ stats.deleted+= mysql->affected_rows;
DBUG_PRINT("info",
("rows deleted %d rows deleted for all time %d",
- int(mysql->affected_rows), deleted));
+ int(mysql->affected_rows), stats.deleted));
DBUG_RETURN(0);
}
@@ -2050,7 +2081,7 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
create_where_from_key(&index_string,
&table->key_info[index],
&range,
- NULL, 0);
+ NULL, 0, 0);
sql_query.append(index_string);
DBUG_PRINT("info",
@@ -2112,15 +2143,10 @@ int ha_federated::index_init(uint keynr, bool sorted)
DBUG_RETURN(0);
}
-/*
- int read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted);
-*/
int ha_federated::read_range_first(const key_range *start_key,
- const key_range *end_key,
- bool eq_range, bool sorted)
+ const key_range *end_key,
+ bool eq_range, bool sorted)
{
char sql_query_buffer[FEDERATED_QUERY_BUFFER_SIZE];
int retval;
@@ -2136,7 +2162,7 @@ int ha_federated::read_range_first(const key_range *start_key,
sql_query.append(share->select_query);
create_where_from_key(&sql_query,
&table->key_info[active_index],
- start_key, end_key, 0);
+ start_key, end_key, 0, eq_range);
if (mysql_real_query(mysql, sql_query.ptr(), sql_query.length()))
{
@@ -2481,18 +2507,20 @@ void ha_federated::info(uint flag)
delete_length = ?
*/
if (row[4] != NULL)
- records= (ha_rows) my_strtoll10(row[4], (char**) 0, &error);
+ stats.records= (ha_rows) my_strtoll10(row[4], (char**) 0,
+ &error);
if (row[5] != NULL)
- mean_rec_length= (ha_rows) my_strtoll10(row[5], (char**) 0, &error);
+ stats.mean_rec_length= (ha_rows) my_strtoll10(row[5], (char**) 0,
+ &error);
if (row[12] != NULL)
- update_time= (ha_rows) my_strtoll10(row[12], (char**) 0, &error);
+ stats.update_time= (ha_rows) my_strtoll10(row[12], (char**) 0,
+ &error);
if (row[13] != NULL)
- check_time= (ha_rows) my_strtoll10(row[13], (char**) 0, &error);
+ stats.check_time= (ha_rows) my_strtoll10(row[13], (char**) 0,
+ &error);
}
if (flag & HA_STATUS_CONST)
- {
- block_size= 4096;
- }
+ stats.block_size= 4096;
}
if (result)
@@ -2543,8 +2571,8 @@ int ha_federated::delete_all_rows()
{
DBUG_RETURN(stash_remote_error());
}
- deleted+= records;
- records= 0;
+ stats.deleted+= stats.records;
+ stats.records= 0;
DBUG_RETURN(0);
}
@@ -2822,6 +2850,7 @@ mysql_declare_plugin(federated)
NULL, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
+ 0
}
mysql_declare_plugin_end;