Below is the list of changes that have just been committed into a local
5.1 repository of stewart. When stewart 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, 2006-10-04 17:13:42+10:00, stewart@willster.(none) +2 -0
Merge willster.(none):/home/stewart/Documents/MySQL/5.0/bug19914-mk2
into willster.(none):/home/stewart/Documents/MySQL/5.1/bug19914-mk2
MERGE: 1.1810.2125.15
storage/federated/ha_federated.cc@stripped, 2006-10-04 17:13:38+10:00, stewart@willster.(none) +0 -0
Auto merged
MERGE: 1.24.12.3
storage/federated/ha_federated.cc@stripped, 2006-10-04 17:13:38+10:00, stewart@willster.(none) +0 -0
Merge rename: sql/ha_federated.cc -> storage/federated/ha_federated.cc
storage/federated/ha_federated.h@stripped, 2006-10-04 17:13:38+10:00, stewart@willster.(none) +0 -0
Auto merged
MERGE: 1.18.1.11
storage/federated/ha_federated.h@stripped, 2006-10-04 17:13:38+10:00, stewart@willster.(none) +0 -0
Merge rename: sql/ha_federated.h -> storage/federated/ha_federated.h
# 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: stewart
# Host: willster.(none)
# Root: /home/stewart/Documents/MySQL/5.1/bug19914-mk2/RESYNC
--- 1.24.12.2/sql/ha_federated.cc 2006-10-04 17:13:47 +10:00
+++ 1.83/storage/federated/ha_federated.cc 2006-10-04 17:13:47 +10:00
@@ -333,51 +333,52 @@
*/
+#define MYSQL_SERVER 1
#include "mysql_priv.h"
+#include <mysql/plugin.h>
+
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
#endif
-#ifdef HAVE_FEDERATED_DB
#include "ha_federated.h"
#include "m_string.h"
+
+#include <mysql/plugin.h>
+
/* Variables for federated share methods */
-static HASH federated_open_tables; // Hash used to track open
- // tables
-pthread_mutex_t federated_mutex; // This is the mutex we use to
- // init the hash
-static int federated_init= FALSE; // Variable for checking the
- // init state of hash
+static HASH federated_open_tables; // To track open tables
+pthread_mutex_t federated_mutex; // To init the hash
+static int federated_init= FALSE; // Checking the state of hash
+
+/* Variables used when chopping off trailing characters */
+static const uint sizeof_trailing_comma= sizeof(", ") - 1;
+static const uint sizeof_trailing_closeparen= sizeof(") ") - 1;
+static const uint sizeof_trailing_and= sizeof(" AND ") - 1;
+static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1;
+
+/* Static declaration for handerton */
+static handler *federated_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
+static int federated_commit(handlerton *hton, THD *thd, bool all);
+static int federated_rollback(handlerton *hton, THD *thd, bool all);
+static int federated_db_init(void);
+static int federated_db_end(handlerton *hton, ha_panic_function type);
+
/* Federated storage engine handlerton */
-handlerton federated_hton= {
- "FEDERATED",
- SHOW_OPTION_YES,
- "Federated MySQL storage engine",
- DB_TYPE_FEDERATED_DB,
- federated_db_init,
- 0, /* slot */
- 0, /* savepoint size. */
- NULL, /* close_connection */
- NULL, /* savepoint */
- NULL, /* rollback to savepoint */
- NULL, /* release savepoint */
- NULL, /* commit */
- NULL, /* rollback */
- NULL, /* prepare */
- NULL, /* recover */
- NULL, /* commit_by_xid */
- NULL, /* rollback_by_xid */
- NULL, /* create_cursor_read_view */
- NULL, /* set_cursor_read_view */
- NULL, /* close_cursor_read_view */
- HTON_ALTER_NOT_SUPPORTED
-};
+static handler *federated_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
+{
+ return new (mem_root) ha_federated(hton, table);
+}
-/* Function we use in the creation of our hash to get key. */
+/* Function we use in the creation of our hash to get key */
static byte *federated_get_key(FEDERATED_SHARE *share, uint *length,
my_bool not_used __attribute__ ((unused)))
@@ -398,21 +399,28 @@
TRUE Error
*/
-bool federated_db_init()
+int federated_db_init(void *p)
{
DBUG_ENTER("federated_db_init");
+ handlerton *federated_hton= (handlerton *)p;
+ federated_hton->state= SHOW_OPTION_YES;
+ federated_hton->db_type= DB_TYPE_FEDERATED_DB;
+ federated_hton->commit= federated_commit;
+ federated_hton->rollback= federated_rollback;
+ federated_hton->create= federated_create_handler;
+ federated_hton->panic= federated_db_end;
+ federated_hton->flags= HTON_ALTER_NOT_SUPPORTED;
+
if (pthread_mutex_init(&federated_mutex, MY_MUTEX_INIT_FAST))
goto error;
- if (hash_init(&federated_open_tables, &my_charset_bin, 32, 0, 0,
+ if (!hash_init(&federated_open_tables, &my_charset_bin, 32, 0, 0,
(hash_get_key) federated_get_key, 0, 0))
{
- VOID(pthread_mutex_destroy(&federated_mutex));
- }
- else
- {
federated_init= TRUE;
DBUG_RETURN(FALSE);
}
+
+ VOID(pthread_mutex_destroy(&federated_mutex));
error:
have_federated_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
DBUG_RETURN(TRUE);
@@ -424,13 +432,12 @@
SYNOPSIS
federated_db_end()
- void
RETURN
FALSE OK
*/
-bool federated_db_end()
+int federated_db_end(handlerton *hton, ha_panic_function type)
{
if (federated_init)
{
@@ -438,9 +445,10 @@
VOID(pthread_mutex_destroy(&federated_mutex));
}
federated_init= 0;
- return FALSE;
+ return 0;
}
+
/*
Check (in create) whether the tables exists, and that it can be connected to
@@ -515,19 +523,14 @@
the query will be: SELECT * FROM `tablename` WHERE 1=0
*/
- query.append(FEDERATED_SELECT);
- query.append(FEDERATED_STAR);
- query.append(FEDERATED_FROM);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("SELECT * FROM `"));
escaped_table_name_length=
escape_string_for_mysql(&my_charset_bin, (char*)escaped_table_name,
sizeof(escaped_table_name),
share->table_name,
share->table_name_length);
query.append(escaped_table_name, escaped_table_name_length);
- query.append(FEDERATED_BTICK);
- query.append(FEDERATED_WHERE);
- query.append(FEDERATED_FALSE);
+ query.append(STRING_WITH_LEN("` WHERE 1=0"));
if (mysql_real_query(mysql, query.ptr(), query.length()))
{
@@ -574,12 +577,12 @@
SYNOPSIS
parse_url()
- share pointer to FEDERATED share
- table pointer to current TABLE class
- table_create_flag determines what error to throw
+ share pointer to FEDERATED share
+ table pointer to current TABLE class
+ table_create_flag determines what error to throw
DESCRIPTION
- populates the share with information about the connection
+ Populates the share with information about the connection
to the foreign database that will serve as the data source.
This string must be specified (currently) in the "comment" field,
listed in the CREATE TABLE statement.
@@ -598,7 +601,7 @@
***IMPORTANT***
Currently, only "mysql://" is supported.
- 'password' and 'port' are both optional.
+ 'password' and 'port' are both optional.
RETURN VALUE
0 success
@@ -616,12 +619,12 @@
share->port= 0;
share->socket= 0;
- DBUG_PRINT("info", ("Length %d \n", table->s->connect_string.length));
- DBUG_PRINT("info", ("String %.*s \n", table->s->connect_string.length,
+ DBUG_PRINT("info", ("Length: %d", table->s->connect_string.length));
+ DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length,
table->s->connect_string.str));
- share->scheme= my_strdup_with_length(table->s->connect_string.str,
- table->s->connect_string.length,
- MYF(0));
+ share->scheme= my_strndup(table->s->connect_string.str,
+ table->s->connect_string.length,
+ MYF(0));
share->connect_string_length= table->s->connect_string.length;
DBUG_PRINT("info",("parse_url alloced share->scheme %lx", share->scheme));
@@ -706,8 +709,8 @@
}
DBUG_PRINT("info",
- ("scheme %s username %s password %s \
- hostname %s port %d database %s tablename %s\n",
+ ("scheme: %s username: %s password: %s \
+ hostname: %s port: %d database: %s tablename: %s",
share->scheme, share->username, share->password,
share->hostname, share->port, share->database,
share->table_name));
@@ -723,10 +726,13 @@
** FEDERATED tables
*****************************************************************************/
-ha_federated::ha_federated(TABLE *table_arg)
- :handler(&federated_hton, table_arg),
+ha_federated::ha_federated(handlerton *hton,
+ TABLE_SHARE *table_arg)
+ :handler(hton, table_arg),
mysql(0), stored_result(0)
-{}
+{
+ trx_next= 0;
+}
/*
@@ -747,7 +753,7 @@
RETURN VALUE
0 After fields have had field values stored from record
- */
+*/
uint ha_federated::convert_row_to_internal_format(byte *record,
MYSQL_ROW row,
@@ -755,39 +761,42 @@
{
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(result);
- for (field= table->field; *field; field++)
+ for (field= table->field; *field; field++, row++, lengths++)
{
/*
index variable to move us through the row at the
same iterative step as the field
*/
- int x= field - table->field;
my_ptrdiff_t old_ptr;
old_ptr= (my_ptrdiff_t) (record - table->record[0]);
- (*field)->move_field(old_ptr);
- if (!row[x])
+ (*field)->move_field_offset(old_ptr);
+ if (!*row)
(*field)->set_null();
else
{
- (*field)->set_notnull();
- (*field)->store(row[x], lengths[x], &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(-old_ptr);
+ (*field)->move_field_offset(-old_ptr);
}
-
+ dbug_tmp_restore_column_map(table->write_set, old_map);
DBUG_RETURN(0);
}
static bool emit_key_part_name(String *to, KEY_PART_INFO *part)
{
DBUG_ENTER("emit_key_part_name");
- if (to->append(FEDERATED_BTICK) ||
+ if (to->append(STRING_WITH_LEN("`")) ||
to->append(part->field->field_name) ||
- to->append(FEDERATED_BTICK))
+ to->append(STRING_WITH_LEN("`")))
DBUG_RETURN(1); // Out of memory
DBUG_RETURN(0);
}
@@ -799,7 +808,7 @@
Field *field= part->field;
DBUG_ENTER("emit_key_part_element");
- if (needs_quotes && to->append(FEDERATED_SQUOTE))
+ if (needs_quotes && to->append(STRING_WITH_LEN("'")))
DBUG_RETURN(1);
if (part->type == HA_KEYTYPE_BIT)
@@ -846,10 +855,10 @@
DBUG_RETURN(1);
}
- if (is_like && to->append(FEDERATED_PERCENT))
+ if (is_like && to->append(STRING_WITH_LEN("%")))
DBUG_RETURN(1);
- if (needs_quotes && to->append(FEDERATED_SQUOTE))
+ if (needs_quotes && to->append(STRING_WITH_LEN("'")))
DBUG_RETURN(1);
DBUG_RETURN(0);
@@ -1097,22 +1106,25 @@
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;
@@ -1122,9 +1134,9 @@
if (both_not_null)
{
if (i > 0)
- tmp.append(FEDERATED_CONJUNCTION);
+ tmp.append(STRING_WITH_LEN(") AND ("));
else
- tmp.append(FEDERATED_OPENPAREN);
+ tmp.append(STRING_WITH_LEN(" ("));
}
for (key_part= key_info->key_part,
@@ -1137,7 +1149,7 @@
Field *field= key_part->field;
uint store_length= key_part->store_length;
uint part_length= min(store_length, length);
- needs_quotes= 1;
+ needs_quotes= field->str_needs_quotes();
DBUG_DUMP("key, start of loop", (char *) ptr, length);
if (key_part->null_bit)
@@ -1145,17 +1157,17 @@
if (*ptr++)
{
if (emit_key_part_name(&tmp, key_part) ||
- tmp.append(FEDERATED_ISNULL))
- DBUG_RETURN(1);
+ tmp.append(STRING_WITH_LEN(" IS NULL ")))
+ goto err;
continue;
}
}
- if (tmp.append(FEDERATED_OPENPAREN))
- DBUG_RETURN(1);
+ if (tmp.append(STRING_WITH_LEN(" (")))
+ 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 ||
@@ -1163,118 +1175,129 @@
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);
+ if (tmp.append(STRING_WITH_LEN(" >= ")))
+ goto err;
}
else
{
- if (tmp.append(FEDERATED_EQ))
- DBUG_RETURN(1);
+ if (tmp.append(STRING_WITH_LEN(" = ")))
+ goto err;
}
if (emit_key_part_element(&tmp, key_part, needs_quotes, 0, ptr,
part_length))
- DBUG_RETURN(1);
+ goto err;
}
else
- /* LIKE */
{
+ /* LIKE */
if (emit_key_part_name(&tmp, key_part) ||
- tmp.append(FEDERATED_LIKE) ||
+ tmp.append(STRING_WITH_LEN(" 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);
+ if (tmp.append(STRING_WITH_LEN(" <= ")))
+ goto err;
}
else /* start key */
{
- if (tmp.append(FEDERATED_GT))
- DBUG_RETURN(1);
+ if (tmp.append(STRING_WITH_LEN(" > ")))
+ 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) ||
+ tmp.append(STRING_WITH_LEN(" >= ")) ||
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)
{
if (emit_key_part_name(&tmp, key_part) ||
- tmp.append(FEDERATED_LT) ||
+ tmp.append(STRING_WITH_LEN(" < ")) ||
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) ||
+ tmp.append(STRING_WITH_LEN(" <= ")) ||
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);
+ if (tmp.append(STRING_WITH_LEN(") ")))
+ goto err;
-next_loop:
if (store_length >= length)
break;
DBUG_PRINT("info", ("remainder %d", remainder));
DBUG_ASSERT(remainder > 1);
length-= store_length;
ptr+= store_length;
- if (tmp.append(FEDERATED_AND))
- DBUG_RETURN(1);
+ if (tmp.append(STRING_WITH_LEN(" AND ")))
+ 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))
+ if (tmp.append(STRING_WITH_LEN(") ")))
DBUG_RETURN(1);
- if (to->append(FEDERATED_WHERE))
+ if (to->append(STRING_WITH_LEN(" WHERE ")))
DBUG_RETURN(1);
if (to->append(tmp))
DBUG_RETURN(1);
DBUG_RETURN(0);
+
+err:
+ dbug_tmp_restore_column_map(table->write_set, old_map);
+ DBUG_RETURN(1);
}
/*
@@ -1293,7 +1316,7 @@
/*
In order to use this string, we must first zero it's length,
or it will contain garbage
- */
+ */
query.length(0);
pthread_mutex_lock(&federated_mutex);
@@ -1308,17 +1331,17 @@
connect_string_length)))
{
query.set_charset(system_charset_info);
- query.append(FEDERATED_SELECT);
+ query.append(STRING_WITH_LEN("SELECT "));
for (field= table->field; *field; field++)
{
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("`"));
query.append((*field)->field_name);
- query.append(FEDERATED_BTICK);
- query.append(FEDERATED_COMMA);
+ query.append(STRING_WITH_LEN("`, "));
}
- query.length(query.length()- strlen(FEDERATED_COMMA));
- query.append(FEDERATED_FROM);
- query.append(FEDERATED_BTICK);
+ /* chops off trailing comma */
+ query.length(query.length() - sizeof_trailing_comma);
+
+ query.append(STRING_WITH_LEN(" FROM `"));
if (!(share= (FEDERATED_SHARE *)
my_multi_malloc(MYF(MY_WME),
@@ -1333,7 +1356,7 @@
share->table_name_length= strlen(share->table_name);
/* TODO: share->table_name to LEX_STRING object */
query.append(share->table_name, share->table_name_length);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("`"));
share->select_query= select_query;
strmov(share->select_query, query.ptr());
share->use_count= 0;
@@ -1529,6 +1552,7 @@
DBUG_RETURN(0);
}
+
/*
write_row() inserts a row. No extra() hint is given currently if a bulk load
is happeneding. buf() is a byte array of data. You can use the field
@@ -1545,6 +1569,62 @@
int ha_federated::write_row(byte *buf)
{
+ /*
+ I need a bool again, in 5.0, I used table->s->fields to accomplish this.
+ This worked as a flag that says there are fields with values or not.
+ In 5.1, this value doesn't work the same, and I end up with the code
+ truncating open parenthesis:
+
+ the statement "INSERT INTO t1 VALUES ()" ends up being first built
+ in two strings
+ "INSERT INTO t1 ("
+ and
+ " VALUES ("
+
+ If there are fields with values, they get appended, with commas, and
+ the last loop, a trailing comma is there
+
+ "INSERT INTO t1 ( col1, col2, colN, "
+
+ " VALUES ( 'val1', 'val2', 'valN', "
+
+ Then, if there are fields, it should decrement the string by ", " length.
+
+ "INSERT INTO t1 ( col1, col2, colN"
+ " VALUES ( 'val1', 'val2', 'valN'"
+
+ Then it adds a close paren to both - if there are fields
+
+ "INSERT INTO t1 ( col1, col2, colN)"
+ " VALUES ( 'val1', 'val2', 'valN')"
+
+ Then appends both together
+ "INSERT INTO t1 ( col1, col2, colN) VALUES ( 'val1', 'val2', 'valN')"
+
+ So... the problem, is if you have the original statement:
+
+ "INSERT INTO t1 VALUES ()"
+
+ Which is legitimate, but if the code thinks there are fields
+
+ "INSERT INTO t1 ("
+ " VALUES ( "
+
+ If the field flag is set, but there are no commas, reduces the
+ string by strlen(", ")
+
+ "INSERT INTO t1 "
+ " VALUES "
+
+ Then adds the close parenthesis
+
+ "INSERT INTO t1 )"
+ " VALUES )"
+
+ So, I have to use a bool as before, set in the loop where fields and commas
+ are appended to the string
+ */
+ my_bool commas_added= FALSE;
char insert_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char values_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char insert_field_value_buffer[STRING_BUFFER_USUAL_SIZE];
@@ -1558,11 +1638,12 @@
String insert_field_value_string(insert_field_value_buffer,
sizeof(insert_field_value_buffer),
&my_charset_bin);
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+ DBUG_ENTER("ha_federated::write_row");
+
values_string.length(0);
insert_string.length(0);
insert_field_value_string.length(0);
- DBUG_ENTER("ha_federated::write_row");
-
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();
@@ -1570,68 +1651,72 @@
/*
start both our field and field values strings
*/
- insert_string.append(FEDERATED_INSERT);
- insert_string.append(FEDERATED_BTICK);
+ insert_string.append(STRING_WITH_LEN("INSERT INTO `"));
insert_string.append(share->table_name, share->table_name_length);
- insert_string.append(FEDERATED_BTICK);
- insert_string.append(FEDERATED_OPENPAREN);
+ insert_string.append('`');
+ insert_string.append(STRING_WITH_LEN(" ("));
- values_string.append(FEDERATED_VALUES);
- values_string.append(FEDERATED_OPENPAREN);
+ values_string.append(STRING_WITH_LEN(" VALUES "));
+ values_string.append(STRING_WITH_LEN(" ("));
/*
loop through the field pointer array, add any fields to both the values
- list and the fields list that match the current query id
+ list and the fields list that is part of the write set
*/
for (field= table->field; *field; field++)
{
- if ((*field)->is_null())
- insert_field_value_string.append(FEDERATED_NULL);
- else
+ if (bitmap_is_set(table->write_set, (*field)->field_index))
{
- (*field)->val_str(&insert_field_value_string);
- values_string.append('\'');
- insert_field_value_string.print(&values_string);
- values_string.append('\'');
-
- insert_field_value_string.length(0);
- }
- /* append the field name */
- insert_string.append((*field)->field_name);
+ commas_added= TRUE;
+ if ((*field)->is_null())
+ values_string.append(STRING_WITH_LEN(" NULL "));
+ else
+ {
+ bool needs_quote= (*field)->str_needs_quotes();
+ (*field)->val_str(&insert_field_value_string);
+ if (needs_quote)
+ values_string.append('\'');
+ insert_field_value_string.print(&values_string);
+ if (needs_quote)
+ values_string.append('\'');
- /* append the value */
- values_string.append(insert_field_value_string);
- insert_field_value_string.length(0);
+ insert_field_value_string.length(0);
+ }
+ /* append the field name */
+ insert_string.append((*field)->field_name);
- /* 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)
- */
- insert_string.append(FEDERATED_COMMA);
- values_string.append(FEDERATED_COMMA);
+ /* append commas between both fields and fieldnames */
+ /*
+ 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(STRING_WITH_LEN(", "));
+ values_string.append(STRING_WITH_LEN(", "));
+ }
}
+ 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 ();"
*/
- if (table->s->fields)
+ if (commas_added)
{
+ insert_string.length(insert_string.length() - sizeof_trailing_comma);
/* chops off leading commas */
- values_string.length(values_string.length() - strlen(FEDERATED_COMMA));
- insert_string.append(FEDERATED_CLOSEPAREN);
+ values_string.length(values_string.length() - sizeof_trailing_comma);
+ insert_string.append(STRING_WITH_LEN(") "));
+ }
+ else
+ {
+ /* chops off trailing ) */
+ insert_string.length(insert_string.length() - sizeof_trailing_closeparen);
}
+
/* we always want to append this, even if there aren't any fields */
- values_string.append(FEDERATED_CLOSEPAREN);
+ values_string.append(STRING_WITH_LEN(") "));
/* add the values */
insert_string.append(values_string);
@@ -1656,15 +1741,16 @@
This method ensures that last_insert_id() works properly. What it simply does
is calls last_insert_id() on the foreign database immediately after insert
(if the table has an auto_increment field) and sets the insert id via
- thd->insert_id(ID) (as well as storing thd->prev_insert_id)
+ thd->insert_id(ID)).
*/
void ha_federated::update_auto_increment(void)
{
THD *thd= current_thd;
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));
+ thd->first_successful_insert_id_in_cur_stmt=
+ mysql->last_used_con->insert_id;
+ DBUG_PRINT("info",("last_insert_id %d", stats.auto_increment_value));
DBUG_VOID_RETURN;
}
@@ -1678,10 +1764,9 @@
query.length(0);
query.set_charset(system_charset_info);
- query.append(FEDERATED_OPTIMIZE);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("OPTIMIZE TABLE `"));
query.append(share->table_name, share->table_name_length);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("`"));
if (mysql_real_query(mysql, query.ptr(), query.length()))
{
@@ -1701,16 +1786,15 @@
query.length(0);
query.set_charset(system_charset_info);
- query.append(FEDERATED_REPAIR);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("REPAIR TABLE `"));
query.append(share->table_name, share->table_name_length);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("`"));
if (check_opt->flags & T_QUICK)
- query.append(FEDERATED_QUICK);
+ query.append(STRING_WITH_LEN(" QUICK"));
if (check_opt->flags & T_EXTEND)
- query.append(FEDERATED_EXTENDED);
+ query.append(STRING_WITH_LEN(" EXTENDED"));
if (check_opt->sql_flags & TT_USEFRM)
- query.append(FEDERATED_USE_FRM);
+ query.append(STRING_WITH_LEN(" USE_FRM"));
if (mysql_real_query(mysql, query.ptr(), query.length()))
{
@@ -1727,7 +1811,7 @@
it.
Keep in mind that the server can do updates based on ordering if an ORDER BY
- clause was used. Consecutive ordering is not guarenteed.
+ clause was used. Consecutive ordering is not guaranteed.
Currently new_data will not have an updated auto_increament record, or
and updated timestamp field. You can do these for federated by doing these:
if (table->timestamp_on_update_now)
@@ -1752,8 +1836,9 @@
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
*/
char field_value_buffer[STRING_BUFFER_USUAL_SIZE];
@@ -1772,78 +1857,92 @@
sizeof(where_buffer),
&my_charset_bin);
DBUG_ENTER("ha_federated::update_row");
- /*
+ /*
set string lengths to 0 to avoid misc chars in string
*/
field_value.length(0);
update_string.length(0);
where_string.length(0);
- update_string.append(FEDERATED_UPDATE);
- update_string.append(FEDERATED_BTICK);
+ update_string.append(STRING_WITH_LEN("UPDATE `"));
update_string.append(share->table_name);
- update_string.append(FEDERATED_BTICK);
- update_string.append(FEDERATED_SET);
+ update_string.append(STRING_WITH_LEN("` SET "));
-/*
- In this loop, we want to match column names to values being inserted
- (while building INSERT statement).
+ /*
+ In this loop, we want to match column names to values being inserted
+ (while building INSERT statement).
- Iterate through table->field (new data) and share->old_field (old_data)
- using the same index to create an SQL UPDATE statement. New data is
- used to create SET field=value and old data is used to create WHERE
- field=oldvalue
- */
+ Iterate through table->field (new data) and share->old_field (old_data)
+ using the same index to create an SQL UPDATE statement. New data is
+ used to create SET field=value and old data is used to create WHERE
+ field=oldvalue
+ */
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())
- update_string.append(FEDERATED_NULL);
- else
+ if (bitmap_is_set(table->write_set, (*field)->field_index))
{
- /* otherwise = */
- (*field)->val_str(&field_value);
- update_string.append('\'');
- field_value.print(&update_string);
- update_string.append('\'');
- field_value.length(0);
- }
+ update_string.append((*field)->field_name);
+ update_string.append(STRING_WITH_LEN(" = "));
- 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(&field_value,
- (char*) (old_data + (*field)->offset()));
- where_string.append('\'');
- field_value.print(&where_string);
- where_string.append('\'');
- field_value.length(0);
+ if ((*field)->is_null())
+ update_string.append(STRING_WITH_LEN(" NULL "));
+ else
+ {
+ /* otherwise = */
+ my_bitmap_map *old_map= tmp_use_all_columns(table, table->read_set);
+ bool needs_quote= (*field)->str_needs_quotes();
+ (*field)->val_str(&field_value);
+ if (needs_quote)
+ update_string.append('\'');
+ field_value.print(&update_string);
+ if (needs_quote)
+ update_string.append('\'');
+ field_value.length(0);
+ tmp_restore_column_map(table->read_set, old_map);
+ }
+ update_string.append(STRING_WITH_LEN(", "));
}
- /*
- 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(FEDERATED_AND);
+ where_string.append((*field)->field_name);
+ if (field_in_record_is_null(table, *field, (char*) old_data))
+ where_string.append(STRING_WITH_LEN(" IS NULL "));
+ else
+ {
+ bool needs_quote= (*field)->str_needs_quotes();
+ where_string.append(STRING_WITH_LEN(" = "));
+ (*field)->val_str(&field_value,
+ (char*) (old_data + (*field)->offset()));
+ if (needs_quote)
+ where_string.append('\'');
+ field_value.print(&where_string);
+ if (needs_quote)
+ where_string.append('\'');
+ field_value.length(0);
+ }
+ where_string.append(STRING_WITH_LEN(" AND "));
}
}
- 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() - sizeof_trailing_comma);
+
+ if (where_string.length())
+ {
+ /* chop off trailing AND */
+ where_string.length(where_string.length() - sizeof_trailing_and);
+ update_string.append(STRING_WITH_LEN(" 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!
*/
if (!has_a_primary_key)
- update_string.append(FEDERATED_LIMIT1);
+ update_string.append(STRING_WITH_LEN(" LIMIT 1"));
if (mysql_real_query(mysql, update_string.ptr(), update_string.length()))
{
@@ -1871,54 +1970,60 @@
{
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);
- delete_string.append(FEDERATED_DELETE);
- delete_string.append(FEDERATED_FROM);
- delete_string.append(FEDERATED_BTICK);
+ delete_string.append(STRING_WITH_LEN("DELETE FROM `"));
delete_string.append(share->table_name);
- delete_string.append(FEDERATED_BTICK);
- delete_string.append(FEDERATED_WHERE);
+ delete_string.append(STRING_WITH_LEN("` WHERE "));
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_ISNULL);
- }
- else
+ found++;
+ if (bitmap_is_set(table->read_set, cur_field->field_index))
{
- delete_string.append(FEDERATED_EQ);
- cur_field->val_str(&data_string);
- delete_string.append('\'');
- data_string.print(&delete_string);
- delete_string.append('\'');
+ data_string.length(0);
+ delete_string.append(cur_field->field_name);
+ if (cur_field->is_null())
+ {
+ delete_string.append(STRING_WITH_LEN(" IS NULL "));
+ }
+ else
+ {
+ bool needs_quote= cur_field->str_needs_quotes();
+ delete_string.append(STRING_WITH_LEN(" = "));
+ cur_field->val_str(&data_string);
+ if (needs_quote)
+ delete_string.append('\'');
+ data_string.print(&delete_string);
+ if (needs_quote)
+ delete_string.append('\'');
+ }
+ delete_string.append(STRING_WITH_LEN(" AND "));
}
-
- delete_string.append(FEDERATED_AND);
}
- delete_string.length(delete_string.length()-5); // Remove trailing AND
- delete_string.append(FEDERATED_LIMIT1);
+ // Remove trailing AND
+ delete_string.length(delete_string.length() - sizeof_trailing_and);
+ if (!found)
+ delete_string.length(delete_string.length() - sizeof_trailing_where);
+
+ delete_string.append(STRING_WITH_LEN(" LIMIT 1"));
DBUG_PRINT("info",
("Delete sql: %s", delete_string.c_ptr_quick()));
if (mysql_real_query(mysql, delete_string.ptr(), delete_string.length()))
{
DBUG_RETURN(stash_remote_error());
}
- deleted+= mysql->affected_rows;
- records-= mysql->affected_rows;
+ stats.deleted+= (ha_rows)mysql->affected_rows;
+ stats.records-= (ha_rows)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);
}
@@ -2016,7 +2121,7 @@
create_where_from_key(&index_string,
&table->key_info[index],
&range,
- NULL, 0);
+ NULL, 0, 0);
sql_query.append(index_string);
if (mysql_real_query(mysql, sql_query.ptr(), sql_query.length()))
@@ -2048,7 +2153,7 @@
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
-int ha_federated::index_init(uint keynr)
+int ha_federated::index_init(uint keynr, bool sorted)
{
DBUG_ENTER("ha_federated::index_init");
DBUG_PRINT("info", ("table: '%s' key: %u", table->s->table_name, keynr));
@@ -2078,7 +2183,7 @@
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 (stored_result)
{
@@ -2220,6 +2325,7 @@
DBUG_RETURN(0);
}
+
/*
This is called for each row of the table scan. When you run out of records
you should return HA_ERR_END_OF_FILE. Fill buff up with the row information.
@@ -2270,7 +2376,6 @@
int ha_federated::read_next(byte *buf, MYSQL_RES *result)
{
int retval;
- my_ulonglong num_rows;
MYSQL_ROW row;
DBUG_ENTER("ha_federated::read_next");
@@ -2402,15 +2507,13 @@
if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST))
{
status_query_string.length(0);
- status_query_string.append(FEDERATED_INFO);
- status_query_string.append(FEDERATED_SQUOTE);
-
+ status_query_string.append(STRING_WITH_LEN("SHOW TABLE STATUS LIKE '"));
escape_string_for_mysql(&my_charset_bin, (char *)escaped_table_name,
sizeof(escaped_table_name),
share->table_name,
share->table_name_length);
status_query_string.append(escaped_table_name);
- status_query_string.append(FEDERATED_SQUOTE);
+ status_query_string.append(STRING_WITH_LEN("'"));
if (mysql_real_query(mysql, status_query_string.ptr(),
status_query_string.length()))
@@ -2430,7 +2533,7 @@
if (flag & HA_STATUS_VARIABLE | HA_STATUS_CONST)
{
- /*
+ /*
deleted is set in ha_federated::info
*/
/*
@@ -2442,22 +2545,27 @@
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)
+ stats.mean_rec_length= (ha_rows) my_strtoll10(row[5], (char**) 0, &error);
- mean_rec_length= table->s->reclength;
- data_file_length= records * mean_rec_length;
+ stats.data_file_length= stats.records * stats.mean_rec_length;
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);
}
-
/*
size of IO operations (This is based on a good guess, no high science
involved)
*/
- block_size= 4096;
+ if (flag & HA_STATUS_CONST)
+ stats.block_size= 4096;
+
}
if (result)
@@ -2497,10 +2605,9 @@
query.length(0);
query.set_charset(system_charset_info);
- query.append(FEDERATED_TRUNCATE);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("TRUNCATE `"));
query.append(share->table_name);
- query.append(FEDERATED_BTICK);
+ query.append(STRING_WITH_LEN("`"));
/*
TRUNCATE won't return anything in mysql_affected_rows
@@ -2509,8 +2616,8 @@
{
DBUG_RETURN(stash_remote_error());
}
- deleted+= records;
- records= 0;
+ stats.deleted+= stats.records;
+ stats.records= 0;
DBUG_RETURN(0);
}
@@ -2630,4 +2737,170 @@
DBUG_RETURN(FALSE);
}
-#endif /* HAVE_FEDERATED_DB */
+int ha_federated::external_lock(THD *thd, int lock_type)
+{
+ int error= 0;
+ ha_federated *trx= (ha_federated *)thd->ha_data[ht->slot];
+ DBUG_ENTER("ha_federated::external_lock");
+
+ if (lock_type != F_UNLCK)
+ {
+ DBUG_PRINT("info",("federated not lock F_UNLCK"));
+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ {
+ DBUG_PRINT("info",("federated autocommit"));
+ /*
+ This means we are doing an autocommit
+ */
+ error= connection_autocommit(TRUE);
+ if (error)
+ {
+ DBUG_PRINT("info", ("error setting autocommit TRUE: %d", error));
+ DBUG_RETURN(error);
+ }
+ trans_register_ha(thd, FALSE, ht);
+ }
+ else
+ {
+ DBUG_PRINT("info",("not autocommit"));
+ if (!trx)
+ {
+ /*
+ This is where a transaction gets its start
+ */
+ error= connection_autocommit(FALSE);
+ if (error)
+ {
+ DBUG_PRINT("info", ("error setting autocommit FALSE: %d", error));
+ DBUG_RETURN(error);
+ }
+ thd->ha_data[ht->slot]= this;
+ trans_register_ha(thd, TRUE, ht);
+ /*
+ Send a lock table to the remote end.
+ We do not support this at the moment
+ */
+ if (thd->options & (OPTION_TABLE_LOCK))
+ {
+ DBUG_PRINT("info", ("We do not support lock table yet"));
+ }
+ }
+ else
+ {
+ ha_federated *ptr;
+ for (ptr= trx; ptr; ptr= ptr->trx_next)
+ if (ptr == this)
+ break;
+ else if (!ptr->trx_next)
+ ptr->trx_next= this;
+ }
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+static int federated_commit(handlerton *hton, THD *thd, bool all)
+{
+ int return_val= 0;
+ ha_federated *trx= (ha_federated *)thd->ha_data[hton->slot];
+ DBUG_ENTER("federated_commit");
+
+ if (all)
+ {
+ int error= 0;
+ ha_federated *ptr, *old= NULL;
+ for (ptr= trx; ptr; old= ptr, ptr= ptr->trx_next)
+ {
+ if (old)
+ old->trx_next= NULL;
+ error= ptr->connection_commit();
+ if (error && !return_val);
+ return_val= error;
+ }
+ thd->ha_data[hton->slot]= NULL;
+ }
+
+ DBUG_PRINT("info", ("error val: %d", return_val));
+ DBUG_RETURN(return_val);
+}
+
+
+static int federated_rollback(handlerton *hton, THD *thd, bool all)
+{
+ int return_val= 0;
+ ha_federated *trx= (ha_federated *)thd->ha_data[hton->slot];
+ DBUG_ENTER("federated_rollback");
+
+ if (all)
+ {
+ int error= 0;
+ ha_federated *ptr, *old= NULL;
+ for (ptr= trx; ptr; old= ptr, ptr= ptr->trx_next)
+ {
+ if (old)
+ old->trx_next= NULL;
+ error= ptr->connection_rollback();
+ if (error && !return_val)
+ return_val= error;
+ }
+ thd->ha_data[hton->slot]= NULL;
+ }
+
+ DBUG_PRINT("info", ("error val: %d", return_val));
+ DBUG_RETURN(return_val);
+}
+
+int ha_federated::connection_commit()
+{
+ DBUG_ENTER("ha_federated::connection_commit");
+ DBUG_RETURN(execute_simple_query("COMMIT", 6));
+}
+
+
+int ha_federated::connection_rollback()
+{
+ DBUG_ENTER("ha_federated::connection_rollback");
+ DBUG_RETURN(execute_simple_query("ROLLBACK", 8));
+}
+
+
+int ha_federated::connection_autocommit(bool state)
+{
+ const char *text;
+ DBUG_ENTER("ha_federated::connection_autocommit");
+ text= (state == TRUE) ? "SET AUTOCOMMIT=1" : "SET AUTOCOMMIT=0";
+ DBUG_RETURN(execute_simple_query(text, 16));
+}
+
+
+int ha_federated::execute_simple_query(const char *query, int len)
+{
+ DBUG_ENTER("ha_federated::execute_simple_query");
+
+ if (mysql_real_query(mysql, query, len))
+ {
+ DBUG_RETURN(stash_remote_error());
+ }
+ DBUG_RETURN(0);
+}
+
+struct st_mysql_storage_engine federated_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+
+mysql_declare_plugin(federated)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &federated_storage_engine,
+ "FEDERATED",
+ "Patrick Galbraith and Brian Aker, MySQL AB",
+ "Federated MySQL storage engine",
+ federated_db_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
+
--- 1.18.1.10/sql/ha_federated.h 2006-10-04 17:13:47 +10:00
+++ 1.40/storage/federated/ha_federated.h 2006-10-04 17:13:47 +10:00
@@ -38,85 +38,6 @@
#define FEDERATED_QUERY_BUFFER_SIZE STRING_BUFFER_USUAL_SIZE * 5
#define FEDERATED_RECORDS_IN_RANGE 2
-#define FEDERATED_INFO " SHOW TABLE STATUS LIKE "
-#define FEDERATED_INFO_LEN sizeof(FEDERATED_INFO)
-#define FEDERATED_SELECT "SELECT "
-#define FEDERATED_SELECT_LEN sizeof(FEDERATED_SELECT)
-#define FEDERATED_WHERE " WHERE "
-#define FEDERATED_WHERE_LEN sizeof(FEDERATED_WHERE)
-#define FEDERATED_FROM " FROM "
-#define FEDERATED_FROM_LEN sizeof(FEDERATED_FROM)
-#define FEDERATED_PERCENT "%"
-#define FEDERATED_PERCENT_LEN sizeof(FEDERATED_PERCENT)
-#define FEDERATED_IS " IS "
-#define FEDERATED_IS_LEN sizeof(FEDERATED_IS)
-#define FEDERATED_NULL " NULL "
-#define FEDERATED_NULL_LEN sizeof(FEDERATED_NULL)
-#define FEDERATED_ISNULL " IS NULL "
-#define FEDERATED_ISNULL_LEN sizeof(FEDERATED_ISNULL)
-#define FEDERATED_LIKE " LIKE "
-#define FEDERATED_LIKE_LEN sizeof(FEDERATED_LIKE)
-#define FEDERATED_TRUNCATE "TRUNCATE "
-#define FEDERATED_TRUNCATE_LEN sizeof(FEDERATED_TRUNCATE)
-#define FEDERATED_DELETE "DELETE "
-#define FEDERATED_DELETE_LEN sizeof(FEDERATED_DELETE)
-#define FEDERATED_INSERT "INSERT INTO "
-#define FEDERATED_INSERT_LEN sizeof(FEDERATED_INSERT)
-#define FEDERATED_OPTIMIZE "OPTIMIZE TABLE "
-#define FEDERATED_OPTIMIZE_LEN sizeof(FEDERATED_OPTIMIZE)
-#define FEDERATED_REPAIR "REPAIR TABLE "
-#define FEDERATED_REPAIR_LEN sizeof(FEDERATED_REPAIR)
-#define FEDERATED_QUICK " QUICK"
-#define FEDERATED_QUICK_LEN sizeof(FEDERATED_QUICK)
-#define FEDERATED_EXTENDED " EXTENDED"
-#define FEDERATED_EXTENDED_LEN sizeof(FEDERATED_EXTENDED)
-#define FEDERATED_USE_FRM " USE_FRM"
-#define FEDERATED_USE_FRM_LEN sizeof(FEDERATED_USE_FRM)
-#define FEDERATED_LIMIT1 " LIMIT 1"
-#define FEDERATED_LIMIT1_LEN sizeof(FEDERATED_LIMIT1)
-#define FEDERATED_VALUES "VALUES "
-#define FEDERATED_VALUES_LEN sizeof(FEDERATED_VALUES)
-#define FEDERATED_UPDATE "UPDATE "
-#define FEDERATED_UPDATE_LEN sizeof(FEDERATED_UPDATE)
-#define FEDERATED_SET " SET "
-#define FEDERATED_SET_LEN sizeof(FEDERATED_SET)
-#define FEDERATED_AND " AND "
-#define FEDERATED_AND_LEN sizeof(FEDERATED_AND)
-#define FEDERATED_CONJUNCTION ") AND ("
-#define FEDERATED_CONJUNCTION_LEN sizeof(FEDERATED_CONJUNCTION)
-#define FEDERATED_OR " OR "
-#define FEDERATED_OR_LEN sizeof(FEDERATED_OR)
-#define FEDERATED_NOT " NOT "
-#define FEDERATED_NOT_LEN sizeof(FEDERATED_NOT)
-#define FEDERATED_STAR "* "
-#define FEDERATED_STAR_LEN sizeof(FEDERATED_STAR)
-#define FEDERATED_SPACE " "
-#define FEDERATED_SPACE_LEN sizeof(FEDERATED_SPACE)
-#define FEDERATED_SQUOTE "'"
-#define FEDERATED_SQUOTE_LEN sizeof(FEDERATED_SQUOTE)
-#define FEDERATED_COMMA ", "
-#define FEDERATED_COMMA_LEN sizeof(FEDERATED_COMMA)
-#define FEDERATED_BTICK "`"
-#define FEDERATED_BTICK_LEN sizeof(FEDERATED_BTICK)
-#define FEDERATED_OPENPAREN " ("
-#define FEDERATED_OPENPAREN_LEN sizeof(FEDERATED_OPENPAREN)
-#define FEDERATED_CLOSEPAREN ") "
-#define FEDERATED_CLOSEPAREN_LEN sizeof(FEDERATED_CLOSEPAREN)
-#define FEDERATED_NE " != "
-#define FEDERATED_NE_LEN sizeof(FEDERATED_NE)
-#define FEDERATED_GT " > "
-#define FEDERATED_GT_LEN sizeof(FEDERATED_GT)
-#define FEDERATED_LT " < "
-#define FEDERATED_LT_LEN sizeof(FEDERATED_LT)
-#define FEDERATED_LE " <= "
-#define FEDERATED_LE_LEN sizeof(FEDERATED_LE)
-#define FEDERATED_GE " >= "
-#define FEDERATED_GE_LEN sizeof(FEDERATED_GE)
-#define FEDERATED_EQ " = "
-#define FEDERATED_EQ_LEN sizeof(FEDERATED_EQ)
-#define FEDERATED_FALSE " 1=0"
-#define FEDERATED_FALSE_LEN sizeof(FEDERATED_FALSE)
-
/*
FEDERATED_SHARE is a structure that will be shared amoung all open handlers
The example implements the minimum of what you will probably need.
@@ -166,20 +87,22 @@
*/
uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row,
MYSQL_RES *result);
- bool create_where_from_key(String *to, KEY *key_info,
+ bool 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);
int stash_remote_error();
public:
- ha_federated(TABLE *table_arg);
- ~ha_federated()
- {
- }
+ ha_federated(handlerton *hton, TABLE_SHARE *table_arg);
+ ~ha_federated() {}
/* The name that will be used for display purposes */
const char *table_type() const { return "FEDERATED"; }
/*
+ Next pointer used in transaction
+ */
+ ha_federated *trx_next;
+ /*
The name of the index type that will be used for display
don't implement this method unless you really have indexes
*/
@@ -191,14 +114,13 @@
implements. The current table flags are documented in
handler.h
*/
- ulong table_flags() const
+ ulonglong table_flags() const
{
/* fix server to be able to get remote server table flags */
- return (HA_NOT_EXACT_COUNT |
- HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | HA_REC_NOT_IN_SEQ |
- HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS| HA_NO_PREFIX_CHAR_KEYS |
- HA_NULL_IN_KEY
- );
+ return (HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED
+ | HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS |
+ HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE |
+ HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY);
}
/*
This is a bitmap of flags that says how the storage engine
@@ -232,9 +154,8 @@
*/
double scan_time()
{
- DBUG_PRINT("info",
- ("records %d", records));
- return (double)(records*1000);
+ DBUG_PRINT("info", ("records %lu", (ulong) stats.records));
+ return (double)(stats.records*1000);
}
/*
The next method will never be called if you do not implement indexes.
@@ -261,7 +182,7 @@
int write_row(byte *buf);
int update_row(const byte *old_data, byte *new_data);
int delete_row(const byte *buf);
- int index_init(uint keynr);
+ int index_init(uint keynr, bool sorted);
int index_read(byte *buf, const byte *key,
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte *buf, uint idx, const byte *key,
@@ -301,6 +222,11 @@
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); //required
virtual bool get_error_message(int error, String *buf);
+ int external_lock(THD *thd, int lock_type);
+ int connection_commit();
+ int connection_rollback();
+ int connection_autocommit(bool state);
+ int execute_simple_query(const char *query, int len);
int read_next(byte *buf, MYSQL_RES *result);
int index_read_idx_with_result_set(byte *buf, uint index,
@@ -310,5 +236,3 @@
MYSQL_RES **result);
};
-bool federated_db_init(void);
-bool federated_db_end(void);
| Thread |
|---|
| • bk commit into 5.1 tree (stewart:1.2343) | Stewart Smith | 4 Oct |