Commit 0d0aa7a4 authored by unknown's avatar unknown

Merge pgalbraith@bk-internal.mysql.com:/home/bk/mysql-5.0

into  krsna.patg.net:/home/patg/mysql-5.0

parents e155a0c0 6771f8d0
--source ./include/have_federated_db.inc
source ./include/master-slave.inc;
# remote table creation
connection slave;
--replicate-ignore-db=federated
stop slave;
--disable_warnings
# at this point, we are connected to master
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
connection master;
--disable_warnings
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
connection master;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
connection slave;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -26,15 +26,51 @@ ...@@ -26,15 +26,51 @@
#endif #endif
#include <mysql.h> #include <mysql.h>
//#include <client.h>
#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_SELECT "SELECT "
#define FEDERATED_WHERE " WHERE "
#define FEDERATED_FROM " FROM "
#define FEDERATED_PERCENT "%"
#define FEDERATED_IS " IS "
#define FEDERATED_NULL " NULL "
#define FEDERATED_ISNULL " IS NULL "
#define FEDERATED_LIKE " LIKE "
#define FEDERATED_TRUNCATE "TRUNCATE "
#define FEDERATED_DELETE "DELETE "
#define FEDERATED_INSERT "INSERT INTO "
#define FEDERATED_LIMIT1 " LIMIT 1"
#define FEDERATED_VALUES "VALUES "
#define FEDERATED_UPDATE "UPDATE "
#define FEDERATED_SET "SET "
#define FEDERATED_AND " AND "
#define FEDERATED_CONJUNCTION ") AND ("
#define FEDERATED_OR " OR "
#define FEDERATED_NOT " NOT "
#define FEDERATED_STAR "* "
#define FEDERATED_SPACE " "
#define FEDERATED_SQUOTE "'"
#define FEDERATED_COMMA ", "
#define FEDERATED_DQOUTE '"'
#define FEDERATED_BTICK "`"
#define FEDERATED_OPENPAREN " ("
#define FEDERATED_CLOSEPAREN ") "
#define FEDERATED_NE " != "
#define FEDERATED_GT " > "
#define FEDERATED_LT " < "
#define FEDERATED_LE " <= "
#define FEDERATED_GE " >= "
#define FEDERATED_EQ " = "
#define FEDERATED_1EQ0 " 1=0"
/* /*
FEDERATED_SHARE is a structure that will be shared amoung all open handlers FEDERATED_SHARE is a structure that will be shared amoung all open handlers
The example implements the minimum of what you will probably need. The example implements the minimum of what you will probably need.
*/ */
typedef struct st_federated_share { typedef struct st_federated_share {
char *table_name;
char *table_base_name;
/* /*
the primary select query to be used in rnd_init the primary select query to be used in rnd_init
*/ */
...@@ -47,11 +83,12 @@ typedef struct st_federated_share { ...@@ -47,11 +83,12 @@ typedef struct st_federated_share {
char *username; char *username;
char *password; char *password;
char *database; char *database;
char *table_name;
char *table; char *table;
char *socket; char *socket;
char *sport; char *sport;
int port; ushort port;
uint table_name_length,table_base_name_length,use_count; uint table_name_length,use_count;
pthread_mutex_t mutex; pthread_mutex_t mutex;
THR_LOCK lock; THR_LOCK lock;
} FEDERATED_SHARE; } FEDERATED_SHARE;
...@@ -63,8 +100,8 @@ class ha_federated: public handler ...@@ -63,8 +100,8 @@ class ha_federated: public handler
{ {
THR_LOCK_DATA lock; /* MySQL lock */ THR_LOCK_DATA lock; /* MySQL lock */
FEDERATED_SHARE *share; /* Shared lock info */ FEDERATED_SHARE *share; /* Shared lock info */
MYSQL *mysql; MYSQL *mysql; /* MySQL connection */
MYSQL_RES *result; MYSQL_RES *stored_result;
bool scan_flag; bool scan_flag;
uint ref_length; uint ref_length;
uint fetch_num; // stores the fetch num uint fetch_num; // stores the fetch num
...@@ -77,11 +114,13 @@ private: ...@@ -77,11 +114,13 @@ private:
*/ */
uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row); uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row);
bool create_where_from_key(String *to, KEY *key_info, bool create_where_from_key(String *to, KEY *key_info,
const byte *key, uint key_length); const key_range *start_key,
const key_range *end_key,
bool records_in_range);
public: public:
ha_federated(TABLE *table): handler(table), ha_federated(TABLE *table): handler(table),
mysql(0), result(0), scan_flag(0), mysql(0), stored_result(0), scan_flag(0),
ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0) ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0)
{ {
} }
...@@ -94,20 +133,20 @@ public: ...@@ -94,20 +133,20 @@ public:
The name of the index type that will be used for display The name of the index type that will be used for display
don't implement this method unless you really have indexes don't implement this method unless you really have indexes
*/ */
// perhaps get index type
const char *index_type(uint inx) { return "REMOTE"; } const char *index_type(uint inx) { return "REMOTE"; }
const char **bas_ext() const; const char **bas_ext() const;
/* /*
This is a list of flags that says what the storage engine This is a list of flags that says what the storage engine
implements. The current table flags are documented in implements. The current table flags are documented in
handler.h handler.h
Serg: Double check these (Brian)
// FIX add blob support
*/ */
ulong table_flags() const ulong table_flags() const
{ {
return (HA_TABLE_SCAN_ON_INDEX | HA_NOT_EXACT_COUNT | /* fix server to be able to get remote server table flags */
HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | return (HA_NOT_EXACT_COUNT |
HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS); 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);
} }
/* /*
This is a bitmap of flags that says how the storage engine This is a bitmap of flags that says how the storage engine
...@@ -119,29 +158,45 @@ public: ...@@ -119,29 +158,45 @@ public:
If all_parts it's set, MySQL want to know the flags for the combined If all_parts it's set, MySQL want to know the flags for the combined
index up to and including 'part'. index up to and including 'part'.
*/ */
/* fix server to be able to get remote server index flags */
ulong index_flags(uint inx, uint part, bool all_parts) const ulong index_flags(uint inx, uint part, bool all_parts) const
{ {
return (HA_READ_NEXT); return (HA_READ_NEXT | HA_READ_RANGE | HA_READ_AFTER_KEY);
// return (HA_READ_NEXT | HA_ONLY_WHOLE_INDEX);
} }
uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_supported_keys() const { return MAX_KEY; } uint max_supported_keys() const { return MAX_KEY; }
uint max_supported_key_parts() const { return 1024; } uint max_supported_key_parts() const { return MAX_REF_PARTS; }
uint max_supported_key_length() const { return 1024; } uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
/* /*
Called in test_quick_select to determine if indexes should be used. Called in test_quick_select to determine if indexes should be used.
Normally, we need to know number of blocks . For federated we need to
know number of blocks on remote side, and number of packets and blocks
on the network side (?)
Talk to Kostja about this - how to get the
number of rows * ...
disk scan time on other side (block size, size of the row) + network time ...
The reason for "records * 1000" is that such a large number forces
this to use indexes "
*/ */
virtual double scan_time() double scan_time()
{ {
DBUG_PRINT("ha_federated::scan_time", DBUG_PRINT("info",
("rows %d", records)); return (double)(records*2); ("records %d", records));
return (double)(records*1000);
} }
/* /*
The next method will never be called if you do not implement indexes. The next method will never be called if you do not implement indexes.
*/ */
virtual double read_time(uint index, uint ranges, ha_rows rows) double read_time(uint index, uint ranges, ha_rows rows)
{ return (double) rows / 20.0+1; } {
/*
Per Brian, this number is bugus, but this method must be implemented,
and at a later date, he intends to document this issue for handler code
*/
return (double) rows / 20.0+1;
}
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
/* /*
Everything below are methods that we implment in ha_federated.cc. Everything below are methods that we implment in ha_federated.cc.
...@@ -151,16 +206,20 @@ public: ...@@ -151,16 +206,20 @@ public:
int open(const char *name, int mode, uint test_if_locked); // required int open(const char *name, int mode, uint test_if_locked); // required
int close(void); // required int close(void); // required
int write_row(byte * buf); int write_row(byte *buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte *old_data, byte *new_data);
int delete_row(const byte * buf); int delete_row(const byte *buf);
int index_init(uint keynr); int index_init(uint keynr);
int index_read(byte * buf, const byte * key, int index_read(byte *buf, const byte *key,
uint key_len, enum ha_rkey_function find_flag); uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key, int index_read_idx(byte *buf, uint idx, const byte *key,
uint key_len, enum ha_rkey_function find_flag); uint key_len, enum ha_rkey_function find_flag);
int index_next(byte * buf); int index_next(byte *buf);
int index_end(); int index_end();
int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
int read_range_next();
/* /*
unlike index_init(), rnd_init() can be called two times unlike index_init(), rnd_init() can be called two times
without rnd_end() in between (it only makes sense if scan=1). without rnd_end() in between (it only makes sense if scan=1).
...@@ -172,13 +231,15 @@ public: ...@@ -172,13 +231,15 @@ public:
int rnd_init(bool scan); //required int rnd_init(bool scan); //required
int rnd_end(); int rnd_end();
int rnd_next(byte *buf); //required int rnd_next(byte *buf); //required
int rnd_pos(byte * buf, byte *pos); //required int rnd_pos(byte *buf, byte *pos); //required
void position(const byte *record); //required void position(const byte *record); //required
void info(uint); //required void info(uint); //required
int delete_all_rows(void); int delete_all_rows(void);
int create(const char *name, TABLE *form, int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); //required HA_CREATE_INFO *create_info); //required
ha_rows records_in_range(uint inx, key_range *start_key,
key_range *end_key);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); //required enum thr_lock_type lock_type); //required
......
...@@ -5370,3 +5370,15 @@ ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009 ...@@ -5370,3 +5370,15 @@ ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009
eng "Scale may not be larger than the precision (column '%-.64s')." eng "Scale may not be larger than the precision (column '%-.64s')."
ER_WRONG_LOCK_OF_SYSTEM_TABLE ER_WRONG_LOCK_OF_SYSTEM_TABLE
eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables" eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables"
ER_CONNECT_TO_FOREIGN_DATA_SOURCE
eng "Unable to connect to foreign data source - database '%s'!"
ER_QUERY_ON_FOREIGN_DATA_SOURCE
eng "There was a problem processing the query on the foreign data source. Data source error: '%-.64s'"
ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST
eng "The foreign data source you are trying to reference does not exist. Data source error : '%-.64s'"
ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE
eng "Can't create federated table. The data source connection string '%-.64s' is not in the correct format"
ER_FOREIGN_DATA_STRING_INVALID
eng "The data source connection string '%-.64s' is not in the correct format"
ER_CANT_CREATE_FEDERATED_TABLE
eng "Can't create federated table. Foreign data src error : '%-.64s'"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment