List:Internals« Previous MessageNext Message »
From:Patrick Galbraith Date:March 15 2005 8:32am
Subject:bk commit into 5.0 tree (patg:1.1814)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of patg. When patg 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
  1.1814 05/03/15 00:32:21 patg@krsna. +4 -0
  This changeset contains changes approved in code review by 
  Konstja and Georg, change sets 1.1806, 1.1805. These changes has been successfully 
  tested on both my own workstation (Suse 9.0) and production.mysql.com.

  BitKeeper/etc/logging_ok
    1.299 05/03/15 00:32:20 patg@krsna. +1 -0
    Logging to logging@stripped accepted

  sql/ha_federated.cc
    1.19 05/03/15 00:20:13 patg@krsna. +155 -22
    - check_foreign_data source added
    - table names now enclosed in '`' to allow for '%' or other characters
    - better error handling
    - mysql_init now checked to see if it returns true/false, error out if false (Georg)

  mysql-test/t/federated.test
    1.6 05/03/15 00:20:13 patg@krsna. +146 -18
    new error handling tests

  mysql-test/r/federated.result
    1.7 05/03/15 00:20:13 patg@krsna. +114 -2
    new test results for error handling tests.

# 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:	patg
# Host:	krsna.
# Root:	/home/patg/test/mysql-5.0

--- 1.298/BitKeeper/etc/logging_ok	Wed Mar  9 04:36:55 2005
+++ 1.299/BitKeeper/etc/logging_ok	Tue Mar 15 00:32:20 2005
@@ -182,6 +182,7 @@
 nick@stripped
 nick@stripped
 papa@stripped
+patg@krsna.
 patg@stripped
 patg@stripped
 patg@stripped

--- 1.6/mysql-test/r/federated.result	Wed Feb 23 00:38:23 2005
+++ 1.7/mysql-test/r/federated.result	Tue Mar 15 00:20:13 2005
@@ -8,6 +8,120 @@
 DROP DATABASE IF EXISTS federated;
 CREATE DATABASE federated;
 CREATE TABLE federated.t1 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+DEFAULT CHARSET=latin1;
+DROP DATABASE IF EXISTS federated;
+CREATE DATABASE federated;
+CREATE TABLE federated.t1 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://root@stripped:@/too/many/items/federated/t1';
+ERROR HY000: Can't create table 'this connection string is not in the correct format!
+' (errno: 0)
+CREATE TABLE federated.t1 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://root@stripped';
+ERROR HY000: Can't create table 'this connection string is not in the correct format!
+' (errno: 0)
+CREATE TABLE federated.t1 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://root@stripped:SLAVE_PORT/federated/t3';
+ERROR HY000: Error running query on master: foreign table 't3' does not exist!
+CREATE TABLE federated.t1 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://user:pass@stripped:SLAVE_PORT/federated/t1';
+ERROR 08S01: Error connecting to master: unable to connect to database 'federated' on host '127.0.0.1 as user 'user' !
+DROP TABLE IF EXISTS federated.t1;
+Warnings:
+Note	1051	Unknown table 't1'
+CREATE TABLE federated.t1 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://root@stripped:SLAVE_PORT/federated/t1';
+INSERT INTO federated.t1 (id, name) VALUES (1, 'foo');
+INSERT INTO federated.t1 (id, name) VALUES (2, 'fee');
+SELECT * FROM federated.t1;
+id	name
+1	foo
+2	fee
+DELETE FROM federated.t1;
+DROP TABLE federated.t1;
+DROP TABLE IF EXISTS federated.t2;
+Warnings:
+Note	1051	Unknown table 't2'
+CREATE TABLE federated.t2 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://root@stripped:SLAVE_PORT/federated/t1';
+INSERT INTO federated.t2 (id, name) VALUES (1, 'foo');
+INSERT INTO federated.t2 (id, name) VALUES (2, 'fee');
+SELECT * FROM federated.t2;
+id	name
+1	foo
+2	fee
+DROP TABLE federated.t2;
+DROP TABLE IF EXISTS federated.t1;
+DROP TABLE IF EXISTS federated.`t1%`;
+Warnings:
+Note	1051	Unknown table 't1%'
+CREATE TABLE federated.`t1%` (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS federated.t1;
+Warnings:
+Note	1051	Unknown table 't1'
+CREATE TABLE federated.t1 (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://root@stripped:SLAVE_PORT/federated/t1%';
+INSERT INTO federated.t1 (id, name) VALUES (1, 'foo');
+INSERT INTO federated.t1 (id, name) VALUES (2, 'fee');
+SELECT * FROM federated.t1;
+id	name
+1	foo
+2	fee
+DELETE FROM federated.t1;
+DROP TABLE IF EXISTS federated.t1;
+CREATE TABLE federated.`t1%` (
+`id` int(20) NOT NULL,
+`name` varchar(32) NOT NULL default ''
+    )
+ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+COMMENT='mysql://root@stripped:9308/federated/t1%';
+INSERT INTO federated.`t1%` (id, name) VALUES (1, 'foo');
+INSERT INTO federated.`t1%` (id, name) VALUES (2, 'fee');
+SELECT * FROM federated.`t1%`;
+id	name
+1	foo
+2	fee
+DELETE FROM federated.`t1%`;
+DROP TABLE IF EXISTS federated.`t1%`;
+DROP TABLE IF EXISTS federated.`t1%`;
+DROP TABLE IF EXISTS federated.t1;
+Warnings:
+Note	1051	Unknown table 't1'
+CREATE TABLE federated.t1 (
 `id` int(20) NOT NULL auto_increment,
 `name` varchar(32) NOT NULL default '',
 `other` int(20) NOT NULL default '0',
@@ -16,8 +130,6 @@
 KEY `name` (`name`),
 KEY `other_key` (`other`))
 DEFAULT CHARSET=latin1;
-DROP DATABASE IF EXISTS federated;
-CREATE DATABASE federated;
 CREATE TABLE federated.t1 (
 `id` int(20) NOT NULL auto_increment,
 `name` varchar(32) NOT NULL default '',

--- 1.5/mysql-test/t/federated.test	Wed Feb 23 00:38:23 2005
+++ 1.6/mysql-test/t/federated.test	Tue Mar 15 00:20:13 2005
@@ -14,7 +14,136 @@
 --enable_warnings
 CREATE DATABASE federated;
 
+CREATE TABLE federated.t1 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  DEFAULT CHARSET=latin1;
+
+connection master;
+--disable_warnings
+DROP DATABASE IF EXISTS federated;
+--enable_warnings
+CREATE DATABASE federated;
+
+# test too many items (malformed) in the comment string url
+--error 1005
+eval CREATE TABLE federated.t1 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://root@stripped:@/too/many/items/federated/t1';
+
+# test not enough items (malformed) in the comment string url
+--error 1005
+eval CREATE TABLE federated.t1 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://root@stripped';
+
+# test non-existant table
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+--error 1219 
+eval CREATE TABLE federated.t1 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://root@stripped:$SLAVE_MYPORT/federated/t3';
+
+# test bad user/password 
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+--error 1218
+eval CREATE TABLE federated.t1 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://user:pass@stripped:$SLAVE_MYPORT/federated/t1';
+
+DROP TABLE IF EXISTS federated.t1;
+# # correct connection, same named tables
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE federated.t1 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://root@stripped:$SLAVE_MYPORT/federated/t1';
+
+INSERT INTO federated.t1 (id, name) VALUES (1, 'foo');
+INSERT INTO federated.t1 (id, name) VALUES (2, 'fee');
+
+SELECT * FROM federated.t1;
+DELETE FROM federated.t1;
+DROP TABLE federated.t1;
+
+# correct connection, differently named tables
+DROP TABLE IF EXISTS federated.t2;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE federated.t2 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://root@stripped:$SLAVE_MYPORT/federated/t1';
+
+INSERT INTO federated.t2 (id, name) VALUES (1, 'foo');
+INSERT INTO federated.t2 (id, name) VALUES (2, 'fee');
+
+SELECT * FROM federated.t2;
+DROP TABLE federated.t2;
+
+connection slave;
+DROP TABLE IF EXISTS federated.t1;
+
+DROP TABLE IF EXISTS federated.`t1%`;
+CREATE TABLE federated.`t1%` (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  DEFAULT CHARSET=latin1;
+
+connection master; 
+DROP TABLE IF EXISTS federated.t1;
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE federated.t1 (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://root@stripped:$SLAVE_MYPORT/federated/t1%';
+
+INSERT INTO federated.t1 (id, name) VALUES (1, 'foo');
+INSERT INTO federated.t1 (id, name) VALUES (2, 'fee');
+
+SELECT * FROM federated.t1;
+DELETE FROM federated.t1;
+DROP TABLE IF EXISTS federated.t1;
+
+eval CREATE TABLE federated.`t1%` (
+    `id` int(20) NOT NULL,
+    `name` varchar(32) NOT NULL default ''
+    )
+  ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+  COMMENT='mysql://root@stripped:$SLAVE_MYPORT/federated/t1%';
+
+INSERT INTO federated.`t1%` (id, name) VALUES (1, 'foo');
+INSERT INTO federated.`t1%` (id, name) VALUES (2, 'fee');
+
+SELECT * FROM federated.`t1%`;
+DELETE FROM federated.`t1%`;
+DROP TABLE IF EXISTS federated.`t1%`;
+
+connection slave;
+DROP TABLE IF EXISTS federated.`t1%`;
+
 # I wanted to use timestamp, but results will fail if so!!!
+DROP TABLE IF EXISTS federated.t1;
 CREATE TABLE federated.t1 (
     `id` int(20) NOT NULL auto_increment,
     `name` varchar(32) NOT NULL default '',
@@ -25,12 +154,8 @@
     KEY `other_key` (`other`))
   DEFAULT CHARSET=latin1;
 
-connection master;
---disable_warnings
-DROP DATABASE IF EXISTS federated;
---enable_warnings
-CREATE DATABASE federated;
 
+connection master;
 --replace_result $SLAVE_MYPORT SLAVE_PORT
 eval CREATE TABLE federated.t1 (
     `id` int(20) NOT NULL auto_increment,
@@ -660,33 +785,36 @@
 INSERT INTO federated.t1 VALUES (0x0100);
 SELECT HEX(a) FROM federated.t1;
 
-
-# TODO
-# 
-# CREATE TABLE federated.t1 
-# (a char(20)) charset=cp1251
-# ENGINE="FEDERATED" COMMENT="mysql://root@stripped:$SLAVE_MYPORT/federated/t1";
-# 
-# connection slave;
+# # simple tests for cyrillic, given to me by 
+# DROP TABLE IF EXISTS federated.t1;
+# --replace_result $SLAVE_MYPORT SLAVE_PORT
+# eval CREATE TABLE federated.t1
+#  (a char(20)) charset=cp1251
+#  ENGINE="FEDERATED" COMMENT="mysql://root@stripped:$SLAVE_MYPORT/federated/t1";
+# # 
+#  connection slave;
 # DROP TABLE IF EXISTS federated.t1;
 # CREATE TABLE federated.t1 (a char(20)) charset=cp1251;
-# 
-# connection master;
+# # 
+#  connection master;
+# SELECT * FROM federated.t1;
 # SET names cp1251;
 # SELECT * FROM federated.t1;
-# select hex(a) from federated.t1;
-# select hex(a) from federated.t1 ORDER BY a desc;
+# SELECT hex(a) from federated.t1;
+# SELECT hex(a) from federated.t1 ORDER BY a desc;
 # SELECT * FROM federated.t1;
 # SELECT * FROM federated.t1;
 # SELECT * FROM federated.t1;
 # SET names default;
+# DROP TABLE IF EXISTS federated.t1;
+
 # 
 # DROP TABLE IF EXISTS federated.t1;
 # 

--- 1.18/sql/ha_federated.cc	Wed Feb 23 00:38:23 2005
+++ 1.19/sql/ha_federated.cc	Tue Mar 15 00:20:13 2005
@@ -414,6 +414,99 @@
   return FALSE;
 }
 
+
+/*
+ Check (in create) whether the tables exists, and that it can be connected to
+
+  SYNOPSIS
+    check_foreign_data_source()
+      share               pointer to FEDERATED share
+
+  DESCRIPTION
+    This method first checks that the connection information that parse url
+    has populated into the share will be sufficient to connect to the foreign
+    table, and if so, does the foreign table exist.
+*/
+
+static int check_foreign_data_source(FEDERATED_SHARE *share)
+{
+  char escaped_table_base_name[IO_SIZE];
+  MYSQL *mysql;
+  MYSQL_RES *result=0;
+  uint error_code;
+  char query_buffer[IO_SIZE];
+  char error_buffer[IO_SIZE];
+  String query(query_buffer, sizeof(query_buffer), &my_charset_bin);
+  DBUG_ENTER("ha_federated::check_foreign_data_source");
+  query.length(0);
+
+  /* error out if we can't alloc memory for mysql_init(NULL) (per Georg) */
+  if (! (mysql= mysql_init(NULL)))
+  {
+    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+  }
+  /* check if we can connect */
+  if (!mysql_real_connect(mysql,
+                          share->hostname,
+                          share->username,
+                          share->password,
+                          share->database,
+                          share->port,
+                          share->socket, 0))
+  {
+    my_sprintf(error_buffer,
+               (error_buffer,
+                "unable to connect to database '%s' on host '%s as user '%s' !",
+               share->database, share->hostname, share->username));
+    error_code= ER_CONNECT_TO_MASTER;
+    goto error;
+  }
+  else
+  {
+    /* 
+      Note: I am not using INORMATION_SCHEMA because this needs to work with < 5.0
+      if we can connect, then make sure the table exists 
+    */
+    query.append("SHOW TABLES LIKE '");
+    escape_string_for_mysql(&my_charset_bin, (char *)escaped_table_base_name,
+                            share->table_base_name,
+                            share->table_base_name_length);
+    query.append(escaped_table_base_name);
+    query.append("'");
+
+    error_code= ER_QUERY_ON_MASTER;
+    if (mysql_real_query(mysql, query.ptr(), query.length()))
+      goto error;
+
+    result= mysql_store_result(mysql);
+    if (! result)
+      goto error;
+
+    /* if ! mysql_num_rows, the table doesn't exist, send error */
+    if (! mysql_num_rows(result))
+    {
+      my_sprintf(error_buffer,
+                 (error_buffer, "foreign table '%s' does not exist!",
+                  share->table_base_name));
+      goto error;
+    }
+    mysql_free_result(result);
+    result= 0;
+    mysql_close(mysql);
+
+  }
+  DBUG_RETURN(0);
+
+error:
+    if (result)
+      mysql_free_result(result);
+    mysql_close(mysql);
+    my_error(error_code, MYF(0), error_buffer);
+    DBUG_RETURN(error_code);
+
+}
+
+
 /*
   Parse connection info from table->s->comment
 
@@ -521,6 +614,8 @@
         }
         else
           goto error;
+
+        share->table_base_name_length= strlen(share->table_base_name);
       }
       else
         goto error;
@@ -545,6 +640,17 @@
                   share->scheme, share->username, share->password,
                   share->hostname, share->port, share->database,
                   share->table_base_name));
+
+      /* If creation, check first if we can connect and that the table exists */
+      /*if (table_create_flag)
+      {
+        if (check_foreign_data_source(share))
+          goto error;
+      */
+        /* free share->schema even if no error, since this is a create */
+      /*
+        my_free((gptr) share->scheme, MYF(0));
+        }*/
     }
     else
       goto error;
@@ -561,6 +667,7 @@
 
 }
 
+
 /*
   Convert MySQL result set row to handler internal format
 
@@ -778,15 +885,14 @@
                                                table_name_length)))
   {
     query.set_charset(system_charset_info);
-    query.append("SELECT * FROM ");
-    query.append(table_base_name);
+    query.append("SELECT * FROM `");
 
     if (!(share= (FEDERATED_SHARE *)
           my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
                           &share, sizeof(*share),
                           &tmp_table_name, table_name_length + 1,
-                          &tmp_table_base_name, table_base_name_length + 1,
-                          &select_query, query.length() + 1, NullS)))
+                          &select_query, query.length() +
+                          strlen(table->s->comment) + 1,  NullS)))
     {
       pthread_mutex_unlock(&federated_mutex);
       return NULL;
@@ -795,14 +901,13 @@
     if (parse_url(share, table, 0))
       goto error;
 
+    query.append(share->table_base_name);
+    query.append("`");
     share->use_count= 0;
     share->table_name_length= table_name_length;
     share->table_name= tmp_table_name;
-    share->table_base_name_length= table_base_name_length;
-    share->table_base_name= tmp_table_base_name;
     share->select_query= select_query;
     strmov(share->table_name, table_name);
-    strmov(share->table_base_name, table_base_name);
     strmov(share->select_query, query.ptr());
     DBUG_PRINT("ha_federated::get_share",
                ("share->select_query %s", share->select_query));
@@ -820,7 +925,6 @@
   pthread_mutex_unlock(&federated_mutex);
   if (share->scheme)
     my_free((gptr) share->scheme, MYF(0));
-  VOID(pthread_mutex_destroy(&share->mutex));
   my_free((gptr) share, MYF(0));
 
   return NULL;
@@ -1016,6 +1120,8 @@
   insert_field_value_string.length(0);
 
   DBUG_ENTER("ha_federated::write_row");
+  DBUG_PRINT("ha_federated::write_row", ("table charset name %s csname %s",
+                                         table->s->table_charset->name, table->s->table_charset->csname));
 
   statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
@@ -1031,8 +1137,9 @@
                                          current_query_id));
 
   /* start off our string */
-  insert_string.append("INSERT INTO ");
+  insert_string.append("INSERT INTO `");
   insert_string.append(share->table_base_name);
+  insert_string.append("`");
   /* start both our field and field values strings */
   insert_string.append(" (");
   values_string.append(" VALUES (");
@@ -1056,7 +1163,7 @@
   for (field= table->field; *field; field++, x++)
   {
     DBUG_PRINT("ha_federated::write_row", ("field type %d", (*field)->type()));
-    // if there is a query id and if it's equal to the current query id
+    /* if there is a query id and if it's equal to the current query id */
     if (((*field)->query_id && (*field)->query_id == current_query_id)
         || all_fields_have_same_query_id)
     {
@@ -1076,8 +1183,7 @@
                     current_query_id, (*field)->query_id));
         (*field)->val_str(&insert_field_value_string);
         /* quote these fields if they require it */
-        (*field)->quote_data(&insert_field_value_string);
-      }
+        (*field)->quote_data(&insert_field_value_string); }
       /* append the field name */
       insert_string.append((*field)->field_name);
 
@@ -1162,20 +1268,19 @@
   /* stores the value to be replaced of the field were are updating */
   String old_field_value(old_field_value_buffer, sizeof(old_field_value_buffer),
                          &my_charset_bin);
-  old_field_value.length(0);
   /* stores the new value of the field */
   String new_field_value(new_field_value_buffer, sizeof(new_field_value_buffer),
                          &my_charset_bin);
-  new_field_value.length(0);
   /* stores the update query */
   String update_string(update_buffer, sizeof(update_buffer), &my_charset_bin);
-  update_string.length(0);
   /* stores the WHERE clause */
   String where_string(where_buffer, sizeof(where_buffer), &my_charset_bin);
-  where_string.length(0);
 
   DBUG_ENTER("ha_federated::update_row");
-
+  old_field_value.length(0);
+  new_field_value.length(0);
+  update_string.length(0);
+  where_string.length(0);
 
   has_a_primary_key= (table->s->primary_key == 0 ? 1 : 0);
   primary_key_field_num= has_a_primary_key ?
@@ -1183,8 +1288,9 @@
   if (has_a_primary_key)
     DBUG_PRINT("ha_federated::update_row", ("has a primary key"));
 
-  update_string.append("UPDATE ");
+  update_string.append("UPDATE `");
   update_string.append(share->table_base_name);
+  update_string.append("`");
   update_string.append(" SET ");
 
 /*
@@ -1312,8 +1418,9 @@
 
   DBUG_ENTER("ha_federated::delete_row");
 
-  delete_string.append("DELETE FROM ");
+  delete_string.append("DELETE FROM `");
   delete_string.append(share->table_base_name);
+  delete_string.append("`");
   delete_string.append(" WHERE ");
 
   for (Field **field= table->field; *field; field++, x++)
@@ -1395,6 +1502,7 @@
   sql_query.length(0);
 
   DBUG_ENTER("ha_federated::index_read_idx");
+
   statistic_increment(table->in_use->status_var.ha_read_key_count,
                       &LOCK_status);
 
@@ -1576,6 +1684,16 @@
   MYSQL_ROW row;
   DBUG_ENTER("ha_federated::rnd_next");
 
+  if (result == 0)
+  {
+    /*
+      Return value of rnd_init is not always checked (see records.cc),
+      so we can get here _even_ if there is _no_ pre-fetched result-set!
+      TODO: fix it.
+      */
+    DBUG_RETURN(1);
+  }
+ 
   /* Fetch a row, insert it back in a row format. */
   current_position= result->data_cursor;
   DBUG_PRINT("ha_federated::rnd_next",
@@ -1716,8 +1834,9 @@
   query.length(0);
 
   query.set_charset(system_charset_info);
-  query.append("TRUNCATE ");
+  query.append("TRUNCATE `");
   query.append(share->table_base_name);
+  query.append("`");
 
   if (mysql_real_query(mysql, query.ptr(), query.length()))
   {
@@ -1803,14 +1922,28 @@
 int ha_federated::create(const char *name, TABLE *table_arg,
                          HA_CREATE_INFO *create_info)
 {
+  int connection_error=0;
   FEDERATED_SHARE tmp;
   DBUG_ENTER("ha_federated::create");
+
   if (parse_url(&tmp, table_arg, 1))
   {
-    my_error(ER_CANT_CREATE_TABLE, MYF(0));
-    DBUG_RETURN(ER_CANT_CREATE_TABLE);
+    my_error(ER_CANT_CREATE_TABLE, MYF(0), name, 1);
+    goto error;
+  }
+  if ((connection_error= check_foreign_data_source(&tmp)))
+  {
+    my_error(connection_error, MYF(0), name, 1);
+    goto error;
   }
+  
   my_free((gptr) tmp.scheme, MYF(0));
   DBUG_RETURN(0);
+  
+error:
+  DBUG_PRINT("ha_federated::create", ("errors, returning %d", ER_CANT_CREATE_TABLE));
+  my_free((gptr) tmp.scheme, MYF(0));
+  DBUG_RETURN(ER_CANT_CREATE_TABLE);
+
 }
 #endif /* HAVE_FEDERATED_DB */
Thread
bk commit into 5.0 tree (patg:1.1814)Patrick Galbraith15 Mar