#At file:///Users/cbell/source/bzr/mysql-6.0-bug-47804/ based on revid:ritheesh.vedire@stripped
2886 Chuck Bell 2009-10-29
BUG#47804 : Backup catalog does not preserve object relationships
The backup catalog contains a reference to triggers that does not
contain all of the information needed to perform object-level
privilege checking. Specifically, the table name for a trigger
is needed to allow object-level privilege checking for triggers.
This patch adds the coordinates for locating a table in the
catalog for all database items. It is currently only used for
triggers but could be helpful for other objects. For all other
objects, the coordinates saved are NULL.
@ mysql-test/suite/backup/r/backup_logs.result
Corrected result file because size of image grew by the size
of the coordinates saved.
@ mysql-test/suite/backup/t/disabled.def
Must disable the restore tests for cross-platform restore tests
because they use a pre-generated backup image. A new patch will
be created once the pushbuild machines are complete and new
backup images pushed to the tree with the tests reenabled.
@ sql/backup/image_info.cc
Added code to find the table for a trigger, locate it in the
catalog, and save its coordinates in the trigger's database
item structure.
@ sql/backup/image_info.h
Added method headers for helper methods to locate a database
and a table in the catalog.
@ sql/backup/stream_v1.c
Added code to read and write the table coordinates for a
trigger from/to the backup image.
@ sql/backup/stream_v1.h
Extended the st_bstream_dbitem_info struct to include the
coordinates for a table. This is only used for triggers.
@ sql/si_objects.cc
Added a new method to find the table for a given trigger.
@ sql/si_objects.h
Added method header for new find table for trigger method.
modified:
mysql-test/suite/backup/r/backup_logs.result
mysql-test/suite/backup/t/disabled.def
sql/backup/image_info.cc
sql/backup/image_info.h
sql/backup/stream_v1.c
sql/backup/stream_v1.h
sql/si_objects.cc
sql/si_objects.h
=== modified file 'mysql-test/suite/backup/r/backup_logs.result'
--- a/mysql-test/suite/backup/r/backup_logs.result 2009-10-12 09:08:34 +0000
+++ b/mysql-test/suite/backup/r/backup_logs.result 2009-10-29 19:29:51 +0000
@@ -260,7 +260,7 @@ backup_state complete
operation backup
error_num 0
num_objects 11
-total_bytes 4223
+total_bytes 4226
validity_point_time #
start_time #
stop_time #
@@ -334,7 +334,7 @@ backup_state complete
operation restore
error_num 0
num_objects 11
-total_bytes 4223
+total_bytes 4226
validity_point_time #
start_time #
stop_time #
=== modified file 'mysql-test/suite/backup/t/disabled.def'
--- a/mysql-test/suite/backup/t/disabled.def 2009-10-12 09:08:34 +0000
+++ b/mysql-test/suite/backup/t/disabled.def 2009-10-29 19:29:51 +0000
@@ -9,4 +9,6 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
-
+backup_xpfm_compat_restore_lctn0 : Need to termporarily disable to get new images from corresponding backup tests. Will reenable with a new patch.
+backup_xpfm_compat_restore_lctn1 : Need to termporarily disable to get new images from corresponding backup tests. Will reenable with a new patch.
+backup_xpfm_compat_restore_lctn2 : Need to termporarily disable to get new images from corresponding backup tests. Will reenable with a new patch.
=== modified file 'sql/backup/image_info.cc'
--- a/sql/backup/image_info.cc 2009-10-21 13:32:24 +0000
+++ b/sql/backup/image_info.cc 2009-10-29 19:29:51 +0000
@@ -260,6 +260,43 @@ Image_info::Dbobj* Image_info::add_db_ob
obj->base.pos= pos;
count_object(type);
+ /*
+ If this is a trigger, get the table for the trigger.
+ */
+ if (type == BSTREAM_IT_TRIGGER)
+ {
+ THD *thd= ::current_thd;
+ obs::Obj *tbl_obj= obs::find_table_for_trigger(thd, &db.name(), &name);
+ if (tbl_obj)
+ {
+ Table *tbl_found;
+ Db *db_found= find_db(db.name());
+
+ if (db_found)
+ tbl_found= db_found->find_table(*tbl_obj->get_name());
+
+ /*
+ Save table's snap and position values.
+ */
+ if (tbl_found)
+ {
+ obj->snap_num= tbl_found->snap_num;
+ obj->pos= tbl_found->base.base.pos;
+ }
+ else
+ {
+ obj->snap_num= 0;
+ obj->pos= 0;
+ }
+ delete tbl_obj;
+ }
+ else
+ {
+ obj->snap_num= 0;
+ obj->pos= 0;
+ }
+ }
+
return obj;
}
@@ -360,7 +397,29 @@ Image_info::get_table(ushort snap_num, u
return tbl;
}
+
+/**
+ Return database stored in the catalogue.
+
+ @param[in] db_name The name of the database.
+
+ @returns Pointer to @c Image_info::Db instance storing information
+ about the database or NULL if the database is not found.
+*/
+Image_info::Db*
+Image_info::find_db(const String &db_name)
+{
+ for (uint n=0; n < db_count(); ++n)
+ {
+ Image_info::Db *db= get_db(n);
+
+ if (db && (db->name() == db_name))
+ return db;
+ else
+ return NULL;
+ }
+}
/**
Find object in the catalogue.
=== modified file 'sql/backup/image_info.h'
--- a/sql/backup/image_info.h 2009-10-21 13:32:24 +0000
+++ b/sql/backup/image_info.h 2009-10-29 19:29:51 +0000
@@ -113,6 +113,7 @@ public: // Public interface.
Ts* get_ts(uint pos) const;
Dbobj* get_db_object(uint db_num, ulong pos) const;
Table* get_table(ushort snap_num, ulong pos) const;
+ Db* find_db(const String &db_name);
// Iterators for enumerating the contents of the archive.
@@ -470,6 +471,8 @@ public:
void add_table(Table&);
/// Description of object.
const char* describe(describe_buf&) const;
+ /// Search for table in database table list.
+ Table* find_table(const String &table_name);
private:
@@ -1179,6 +1182,26 @@ const char* Image_info::Db::describe(des
return buf;
}
+/**
+ Search for a table in the database catalog by name.
+
+ @param[in] table_name The name of the table.
+
+ @returns Pointer to @c Image_info::Table instance storing information
+ about the table or NULL if the table is not found.
+*/
+inline
+Image_info::Table* Image_info::Db::find_table(const String &table_name)
+{
+ for (Table *tbl=first_table; tbl ; tbl= tbl->next_table)
+ {
+ if (tbl->name() == table_name)
+ return tbl;
+
+ if (tbl == last_table)
+ return NULL;
+ }
+}
/// Implementation of @c Image_info::Obj virtual method.
=== modified file 'sql/backup/stream_v1.c'
--- a/sql/backup/stream_v1.c 2009-10-21 13:32:24 +0000
+++ b/sql/backup/stream_v1.c 2009-10-29 19:29:51 +0000
@@ -1000,7 +1000,13 @@ rd_error:
- @c type (2 bytes): Integer object type.
- @c name (variable length): String object name.
-
+ - @note If the object is a trigger, additional information is stored
+ that contains the location of the table on which the trigger fires.
+ - @c snapshot_num (1 byte): Integer indicating which snapshot contains
+ table's data (0-based).
+ - @c table_pos (variable length): Integer position of the table within
+ its snapshot (0-based).
+
Allowable object type values are given in @ref basic_data_itype.
*/
@@ -1041,6 +1047,15 @@ int bstream_wr_db_catalogue(backup_strea
((struct st_bstream_table_info*)item)->snap_num));
CHECK_WR_RES(bstream_wr_num(s, item->base.pos));
}
+
+ /*
+ If this is a trigger, save its table reference to the stream.
+ */
+ if (item->base.type == BSTREAM_IT_TRIGGER)
+ {
+ CHECK_WR_RES(bstream_wr_byte(s, item->snap_num));
+ CHECK_WR_RES(bstream_wr_num(s, item->pos));
+ }
}
bcat_db_iterator_free(cat, db_info, iter);
@@ -1115,6 +1130,16 @@ int bstream_rd_db_catalogue(backup_strea
else
ti.base.base.pos= pos++;
+ /*
+ If this is a trigger, read the table reference information.
+ */
+ if (ti.base.base.type == BSTREAM_IT_TRIGGER)
+ {
+ /* Read table reference. */
+ CHECK_RD_RES(bstream_rd_byte(s, &ti.base.snap_num));
+ CHECK_RD_RES(bstream_rd_num(s, &ti.base.pos));
+ }
+
if (bcat_add_item(cat, &ti.base.base) != BSTREAM_OK)
return BSTREAM_ERROR;
=== modified file 'sql/backup/stream_v1.h'
--- a/sql/backup/stream_v1.h 2009-10-21 13:32:24 +0000
+++ b/sql/backup/stream_v1.h 2009-10-29 19:29:51 +0000
@@ -248,13 +248,20 @@ struct st_bstream_db_info
struct st_bstream_item_info base; /**< The base of the info class. */
};
-
-/** Describes item which sits inside a database. */
+/**
+ Describes item which sits inside a database.
+
+ @note The fields snap_num, pos are used for triggers only and are NULL
+ otherwise. The fields contain the coordinates of the table on which the
+ trigger fires.
+*/
struct st_bstream_dbitem_info
{
struct st_bstream_item_info base;/**< Data common to all items. */
struct st_bstream_db_info *db; /**< Database to which this item belongs. */
+ unsigned short int snap_num; /**< Snapshot where table's data is stored. */
+ unsigned long int pos; /**< Position of the item in image's catalogue. */
};
/**
=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc 2009-10-23 21:26:11 +0000
+++ b/sql/si_objects.cc 2009-10-29 19:29:51 +0000
@@ -3144,6 +3144,65 @@ Obj *find_tablespace_for_table(THD *thd,
///////////////////////////////////////////////////////////////////////////
+/**
+ Retrieve the table name for a trigger
+
+ This method returns a @c Table_obj object for the trigger.
+
+ @param[in] thd Thread context.
+ @param[in] db_name The database name for the trigger.
+ @param[in] trigger_name The trigger name.
+
+ @return Table_obj
+ @retval Table name for trigger.
+ @retval NULL if no table specified.
+*/
+Obj *find_table_for_trigger(THD *thd,
+ const String *db_name,
+ const String *trigger_name)
+{
+ Ed_connection ed_connection(thd);
+ String_stream s_stream;
+ Ed_result_set *ed_result_set;
+
+ s_stream <<
+ "SELECT event_object_table "
+ "FROM INFORMATION_SCHEMA.TRIGGERS "
+ "WHERE trigger_schema = '" << db_name << "' AND "
+ "trigger_name = '" << trigger_name << "'";
+
+
+ if (run_service_interface_sql(thd, &ed_connection,
+ s_stream.lex_string(), TRUE) ||
+ ed_connection.get_warn_count())
+ {
+ /* Should be no warnings. */
+ return NULL;
+ }
+
+ ed_result_set= ed_connection.use_result_set();
+
+ /* The result must contain only one row. */
+ if (ed_result_set->size() != 1)
+ return NULL;
+
+ List_iterator_fast<Ed_row> row_it(*ed_result_set);
+ Ed_row *row= row_it++;
+
+ /* There must be 1 column. */
+ DBUG_ASSERT(row->size() == 1);
+
+ LEX_STRING db;
+ db.str= (char *)db_name->ptr();
+ db.length= db_name->length();
+
+ const LEX_STRING *table_name= row->get_column(0);
+
+ return new Table_obj(db, *table_name);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
bool compare_tablespace_attributes(Obj *ts1, Obj *ts2)
{
DBUG_ENTER("obs::compare_tablespace_attributes");
=== modified file 'sql/si_objects.h'
--- a/sql/si_objects.h 2009-07-15 14:18:59 +0000
+++ b/sql/si_objects.h 2009-10-29 19:29:51 +0000
@@ -412,6 +412,13 @@ Obj *find_tablespace_for_table(THD *thd,
const String *table_name);
/**
+ This method returns the table name for a given trigger.
+*/
+Obj *find_table_for_trigger(THD *thd,
+ const String *db_name,
+ const String *trigger_name);
+
+/**
This method determines if a materialized tablespace exists on the system.
This compares the name and all saved attributes of the tablespace. A
FALSE return would mean either the tablespace does not exist or the
Attachment: [text/bzr-bundle] bzr/charles.bell@sun.com-20091029192951-1kq20qo9ztw968s5.bundle
| Thread |
|---|
| • bzr commit into mysql-6.0-backup branch (charles.bell:2886) Bug#47804 | Chuck Bell | 29 Oct |