List:Commits« Previous MessageNext Message »
From:Rafal Somla Date:April 8 2008 6:25pm
Subject:Re: bk commit into 6.0 tree (cbell:1.2607) WL#4342
View as plain text  
As we discussed over IRC, to simplify things let's skip parsing of the 
serialization string and compare whole serializations to detect if two 
tablespaces are identical.

I would even go as far as not storing the ts attributes inside a ts object - 
only its name and serizalization string. This would be analogous to e.g., 
tables, for which we store only its name (including db name) and serialization 
data. But the final decision is yours.

I'll wait for the updated patch. See also inline for some other comments.

Rafal

cbell@stripped wrote:
> Below is the list of changes that have just been committed into a local
> 6.0 repository of cbell.  When cbell 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, 2008-04-08 10:57:34-04:00, cbell@mysql_cab_desk. +4 -0
>   WL#4342 : ST: extend server service interface to include tablespace objects
>     
>   Patch contains modifications to support backup and restore of Falcon
>   tables with tablespaces.
>     
>   Note: Patch may change pending work ongoing by Falcon team.
> 
>   mysql-test/t/backup_tablespace.test@stripped, 2008-04-08 10:57:29-04:00,
> cbell@mysql_cab_desk. +84 -0
>     WL#4342 : ST: extend server service interface to include tablespace objects
>         
>     New test for tablespace backup and restore (incomplete pending patches
>     for stream and kernel changes).
>     
> 
>   mysql-test/t/backup_tablespace.test@stripped, 2008-04-08 10:57:29-04:00,
> cbell@mysql_cab_desk. +0 -0
> 
>   sql/si_objects.cc@stripped, 2008-04-08 10:57:27-04:00, cbell@mysql_cab_desk. +620 -3
>     WL#4342 : ST: extend server service interface to include tablespace objects
>         
>     This patch adds a new object class to the service interface. This class
>     encapsulates working with tablespaces. Additional helper methods were
>     added to allow the backup kernel code access to macro operations.
>         
>     Note: This is currently limited to Falcon tablespaces.
> 
>   sql/si_objects.h@stripped, 2008-04-08 10:57:27-04:00, cbell@mysql_cab_desk. +36 -0
>     WL#4342 : ST: extend server service interface to include tablespace objects
>         
>     This patch adds a new object class to the service interface. This class
>     encapsulates working with tablespaces. Additional helper methods were
>     added to allow the backup kernel code access to macro operations.
>         
>     Note: This is currently limited to Falcon tablespaces.
> 
>   sql/table.h@stripped, 2008-04-08 10:57:28-04:00, cbell@mysql_cab_desk. +3 -1
>     WL#4342 : ST: extend server service interface to include tablespace objects
>         
>     Added Falcon tablespaces to enum.
> 
> diff -Nrup a/mysql-test/t/backup_tablespace.test
> b/mysql-test/t/backup_tablespace.test
> --- /dev/null	Wed Dec 31 16:00:00 196900
> +++ b/mysql-test/t/backup_tablespace.test	2008-04-08 10:57:29 -04:00
> @@ -0,0 +1,84 @@
> +#
> +# This test includes tests for backup and restore of tables that use
> +# tablespaces.
> +#
> +# Note: This test is limited to the falcon storage engine only.
> +#
> +
> +--source include/have_falcon.inc
> +--source include/not_embedded.inc
> +
> +--disable_warnings
> +DROP DATABASE IF EXISTS backup_ts;
> +--error 0,1
> +--remove_file $MYSQLTEST_VARDIR/master-data/backup_ts.bak;
> +--enable_warnings
> +
> +CREATE DATABASE backup_ts;
> +
> +#
> +# Test 1 - Test backup of database with a table that uses a tablespace
> +#
> +--echo Test 1:
> +--echo Create a tablespace.
> +CREATE TABLESPACE bup_ts ADD DATAFILE 'bup_ts.dat' COMMENT = 'test tablespace
> backup' ENGINE=FALCON;
> +
> +--echo Create tables and add data.
> +CREATE TABLE backup_ts.not_ts (id int, comment char(40)) ENGINE=FALCON;
> +CREATE TABLE backup_ts.has_ts (id int, comment char(40))
> +                               TABLESPACE bup_ts ENGINE=FALCON;
> +
> +# Create some data.
> +INSERT INTO backup_ts.not_ts VALUES (1, "no tablespace 1");
> +INSERT INTO backup_ts.not_ts VALUES (2, "no tablespace 2");
> +INSERT INTO backup_ts.not_ts VALUES (3, "no tablespace 3");
> +INSERT INTO backup_ts.not_ts VALUES (4, "no tablespace 4");
> +INSERT INTO backup_ts.not_ts VALUES (5, "no tablespace 5");
> +
> +INSERT INTO backup_ts.has_ts VALUES (51, "Table has a tablespace 51");
> +INSERT INTO backup_ts.has_ts VALUES (52, "Table has a tablespace 52");
> +INSERT INTO backup_ts.has_ts VALUES (53, "Table has a tablespace 53");
> +INSERT INTO backup_ts.has_ts VALUES (54, "Table has a tablespace 54");
> +INSERT INTO backup_ts.has_ts VALUES (55, "Table has a tablespace 55");
> +
> +# Backup the database with tablespace.
> +--replace_column 1 #
> +BACKUP DATABASE backup_ts TO 'backup_ts.bak';
> +
> +# Drop the database
> +--echo Drop the database.
> +DROP DATABASE backup_ts;
> +
> +# Restore the database and ensure there are no errors.
> +--echo Now restore the database.
> +--replace_column 1 #
> +RESTORE FROM 'backup_ts.bak';
> +
> +--echo Show data
> +SELECT * FROM backup_ts.not_ts;
> +SELECT * FROM backup_ts.has_ts;
> +
> +DROP DATABASE backup_ts;
> +
> +#
> +# Test 2 - Test restore of database throws error when tablespace
> +#          has been altered.
> +#
> +--echo Test 2:
> +--echo Alter the tablespace.
> +DROP TABLESPACE bup_ts;
> +CREATE TABLESPACE bup_ts ADD DATABASE 'different.dat' ENGINE= FALCON;
> +
> +# Restore the database and ensure there is an error.
> +--echo Now restore the database.
> +--error 1200
> +--replace_column 1 #
> +RESTORE FROM 'backup_ts.bak';
> +
> +--echo Cleanup
> +DROP TABLESPACE bup_ts ENGINE=FALCON;
> +DROP DATABASE backup_ts;
> +
> +--error 0,1
> +--remove_file $MYSQLTEST_VARDIR/master-data/backup_ts.bak
> +
> diff -Nrup a/sql/si_objects.cc b/sql/si_objects.cc
> --- a/sql/si_objects.cc	2008-03-23 09:59:06 -04:00
> +++ b/sql/si_objects.cc	2008-04-08 10:57:27 -04:00
> @@ -273,6 +273,12 @@ bool drop_object(THD *thd, const char *o
>  
>    @param[in] thd  Thread context
>    @param[in] st   Schema table enum
> +  @param[in] db_list List of databases for select condition
> +
> +  @note: The select condition is designed to form a WHERE clause based on
> +  the database/schema column of the information_schema views. Most views have
> +  a database/schema column but for those that do not, you must ignore the 
> +  selection condition by passing db_list = NULL.
>  
>    @retval TABLE* The schema table
>  */
> @@ -308,7 +314,13 @@ TABLE* open_schema_table(THD *thd, ST_SC
>  
>    old_map= tmp_use_all_columns(t, t->read_set);
>  
> -  st->fill_table(thd, &arg, obs::create_db_select_condition(thd, t,
> db_list));
> +  /*
> +    Create a selection condition only if db_list is defined.
> +  */
> +  if (db_list)
> +    st->fill_table(thd, &arg, obs::create_db_select_condition(thd, t,
> db_list));
> +  else
> +    st->fill_table(thd, &arg, NULL);
>  
>    tmp_restore_column_map(t->read_set, old_map);
>  
> @@ -698,6 +710,68 @@ private:
>    String m_create_stmt;
>  };
>  
> +/**
> +   @class TablespaceObj
> +
> +   This class provides an abstraction to a user object for creation and
> +   capture of the creation data.
> +*/
> +class TablespaceObj : public Obj
> +{
> +public:
> +  TablespaceObj(const String *ts_name);
> +  
> +public:
> +  virtual bool serialize(THD *thd, String *serialization);
> +
> +  virtual bool materialize(uint serialization_version,
> +                           const String *serialization);
> +
> +  virtual bool execute(THD *thd);
> +
> +  const String *describe();
> +
> +  const String *build_serialization();
> +
> +  /*
> +    The get_db_name primitive is not used for tablespaces.
> +  */
> +  const String *get_db_name() { return 0; }
> +
> +  const String* get_name()
> +  { return &m_ts_name; }
> +
> +  const String* get_datafile()
> +  { return &m_datafile; }
> +
> +  const String* get_comments()
> +  { return &m_comments; }
> +
> +  void set_datafile(const String *df)
> +  { m_datafile.copy(*df); }
> +
> +  void set_comments(const String *c)
> +  { m_comments.copy(*c); }
> +
> +private:
> +  // These attributes are to be used only for serialization.
> +  String m_ts_name;
> +  String m_datafile;
> +  String m_comments;
> +
> +  // Drop is not supported by this object.
> +  bool drop(THD *thd)
> +  { return 0; }
> +
> +  void find_field_in_str(String *search, String *target);
> +
> +  void parse_serialization();
> +
> +private:
> +  // These attributes are to be used only for materialization.
> +  String m_create_stmt;
> +};
> +
>  ///////////////////////////////////////////////////////////////////////////
>  
>  //
> @@ -906,6 +980,7 @@ private:
>    String m_db_name;
>  };
>  
> +
>  ///////////////////////////////////////////////////////////////////////////
>  
>  class ViewBaseObjectsIterator : public ObjIterator
> @@ -962,8 +1037,31 @@ bool InformationSchemaIterator::prepare_
>    enum_schema_tables is_table_idx,
>    List<LEX_STRING> db_list)
>  {
> -  *is_table= open_schema_table(thd, get_schema_table(is_table_idx), &db_list);
> -
> +  ST_SCHEMA_TABLE *st;
> +  /*
> +    The falcon schema table does not conform to the older SHOW 
> +    style fill methods nor does it use a wildcard condition.
> +  */
> +  switch (is_table_idx) {
> +    case SCH_FALCON_TABLESPACES:
> +    {
> +      st= find_schema_table(thd, "FALCON_TABLESPACES");
> +      *is_table= open_schema_table(thd, st, NULL);
> +      break;
> +    }
> +    case SCH_FALCON_TABLESPACE_FILES:
> +    {
> +      st= find_schema_table(thd, "FALCON_TABLESPACE_FILES");
> +      *is_table= open_schema_table(thd, st, NULL);
> +      break;
> +    }
> +    default:
> +    {
> +      st= get_schema_table(is_table_idx);
> +      *is_table= open_schema_table(thd, st, &db_list);
> +      break;
> +    }
> +  }
>    if (!*is_table)
>      return TRUE;
>  
> @@ -2324,6 +2422,215 @@ bool EventObj::drop(THD *thd)
>  
>  ///////////////////////////////////////////////////////////////////////////
>  
> +//
> +// Implementation: TablespaceObj class.
> +//
> +
> +/////////////////////////////////////////////////////////////////////////////
> +
> +TablespaceObj::TablespaceObj(const String *ts_name)
> +{
> +  // copy strings to newly allocated memory
> +  m_ts_name.copy(*ts_name);
> +  m_datafile.length(0);
> +  m_comments.length(0);
> +}
> +
> +/**
> +  Serialize the object.
> +
> +  This method produces the data necessary for materializing the object
> +  on restore (creates object).
> +
> +  @param[in]  thd            Thread context.
> +  @param[out] serialization  The data needed to recreate this object.
> +
> +  @returns Error status.
> +    @retval FALSE on success
> +    @retval TRUE on error
> +*/
> +bool TablespaceObj::serialize(THD *thd, String *serialization)
> +{
> +  DBUG_ENTER("TablespaceObj::serialize()");
> +  if (m_datafile.length() == 0)
> +    DBUG_RETURN(TRUE);   //cannot serialize an invalid tablespace!
> +
> +  build_serialization();
> +  serialization->copy(m_create_stmt);
> +  DBUG_RETURN(FALSE);
> +}
> +
> +/**
> +  Materialize the serialization string.
> +
> +  This method saves serialization string into a member variable.
> +
> +  @param[in]  serialization_version   version number of this interface
> +  @param[in]  serialization           the string from serialize()
> +
> +  @todo take serialization_version into account
> +
> +  @returns Error status.
> +    @retval FALSE on success
> +    @retval TRUE on error
> +*/
> +bool TablespaceObj::materialize(uint serialization_version,
> +                                const String *serialization)
> +{
> +  DBUG_ENTER("TablespaceObj::materialize()");
> +  m_create_stmt.copy(*serialization);
> +  DBUG_RETURN(FALSE);
> +}
> +
> +/**
> +  Get a description of the tablespace object.
> +
> +  This method returns the description of the object which is currently
> +  the serialization string.
> +
> +  @returns Serialization string.
> +*/
> +const String *TablespaceObj::describe()
> +{
> +  DBUG_ENTER("TablespaceObj::describe()");
> +  DBUG_RETURN(build_serialization());
> +}
> +
> +/**
> +  Build the serialization string.
> +
> +  This constructs the serialization string for identification
> +  use in describing tablespace to the user and for creating the
> +  tablespace.
> +
> +  @todo take serialization_version into account
> +
> +  @returns Serialization string.
> +*/
> +const String *TablespaceObj::build_serialization()
> +{
> +  DBUG_ENTER("TablespaceObj::build_serialization()");
> +
> +  if (m_create_stmt.length())
> +    DBUG_RETURN(&m_create_stmt);
> +
> +  /*
> +    Construct the CREATE TABLESPACE command from the variables.
> +  */
> +  m_create_stmt.length(0);
> +  m_create_stmt.append("CREATE TABLESPACE ");
> +  if (m_ts_name.length() > 0)
> +  {
> +    THD *thd= current_thd;
> +    append_identifier(thd, &m_create_stmt, 
> +      m_ts_name.c_ptr(), m_ts_name.length());  
> +  }
> +  m_create_stmt.append(" ADD DATAFILE '");
> +  m_create_stmt.append(m_datafile);
> +  if (m_comments.length())
> +  {
> +    m_create_stmt.append("' COMMENT = '");
> +    m_create_stmt.append(m_comments);
> +  }
> +  m_create_stmt.append("' ENGINE=FALCON");
> +  DBUG_RETURN(&m_create_stmt);
> +}
> +
> +/**
> +  Find the string for missing attribute data.
> +

Should be "Search the sting for ..."?

> +  This method searches the serialization string for the attribute
> +  keyword specified. It returns data found.
> +

Would be helpful to list what keywords are valid.

> +  @param[IN]  search  The attribute keyword for the search
> +  @param[OUT] target  The string to place the data found
> +

This function destroys the search string - would be good to document this.

Looks like this function should return information whether it found anything or not.

> +*/
> +void TablespaceObj::find_field_in_str(String *search, String *target)
> +{
> +  String result;
> +  int loc1;
> +  int loc2;
> +  DBUG_ENTER("TablespaceObj::find_field_in_str()");
> +
> +  result.length(0);
> +  loc1= m_create_stmt.strstr(*search, 0);
> +  if (loc1 != -1)
> +  {
> +    loc1+= search->length();
> +    search->length(0);
> +    search->append("'");
> +    loc2= m_create_stmt.strstr(*search, loc1);
> +    target->copy((m_create_stmt.ptr() + loc1), loc2 - loc1, 
> +      system_charset_info);
> +  }
> +  DBUG_VOID_RETURN;
> +}
> +
> +/**
> +  Parse the serialization string for missing attribute data.
> +
> +  This method searches the serialization string for the datafile
> +  and comment data. This is needed to support the tablespace_exists()
> +  method because the tablespace_exists() method assums the 

s/assums/assumes/

> +  tablespace being compared is a valid tablespace object. A valid
> +  tablespace object for comparison must contain the name, datafile,
> +  and comments (if provided).
> +
> +*/
> +void TablespaceObj::parse_serialization()
> +{
> +  String search;
> +  DBUG_ENTER("TablespaceObj::parse_serialization()");
> +
> +  if (m_datafile.length() == 0)
> +  {
> +    /*
> +      Find DATAFILE clause
> +    */
> +    search.length(0);
> +    search.append("DATAFILE '");
> +    find_field_in_str(&search, &m_datafile);
> +  }
> +  if (m_comments.length() == 0)
> +  {
> +    /*
> +      Find COMMENT clause
> +    */
> +    search.length(0);
> +    search.append("COMMENT = '");
> +    find_field_in_str(&search, &m_comments);
> +  }
> +  DBUG_VOID_RETURN;
> +}
> +
> +/**
> +  Create the object.
> +
> +  This method uses serialization string in a query and executes it.
> +
> +  @param[in]  thd  Thread context.
> +
> +  @returns Error status.
> +    @retval FALSE on success
> +    @retval TRUE on error
> +*/
> +bool TablespaceObj::execute(THD *thd)
> +{
> +  bool ret= FALSE;
> +  DBUG_ENTER("TablespaceObj::execute()");
> +  build_serialization(); // Build the CREATE command.
> +  ret= silent_exec(thd, &m_create_stmt);
> +  /*
> +    If the create worked, now we need to get the other attributes
> +    embedded in the serialization string.
> +  */
> +  parse_serialization();
> +  DBUG_RETURN(ret);
> +}
> +
> +///////////////////////////////////////////////////////////////////////////
> +
>  Obj *get_database(const String *db_name)
>  {
>    return new DatabaseObj(db_name);
> @@ -2443,6 +2750,16 @@ Obj *materialize_event(const String *db_
>    return obj;
>  }
>  
> +Obj *materialize_tablespace(const String *ts_name,
> +                            uint serialization_version,
> +                            const String *serialialization)
> +{
> +  Obj *obj= new TablespaceObj(ts_name);
> +  obj->materialize(serialization_version, serialialization);

Why not to parse the serialization string here, so that we obtain a "valid" 
tablespace object?

> +
> +  return obj;
> +}
> +
>  ///////////////////////////////////////////////////////////////////////////
>  
>  bool is_internal_db_name(const String *db_name)
> @@ -2464,6 +2781,306 @@ bool is_internal_db_name(const String *d
>  bool check_db_existence(const String *db_name)
>  {
>    return check_db_dir_existence(((String *) db_name)->c_ptr_safe());
> +}
> +
> +/**
> +  Locate the row in the information_schema view for this tablespace.
> +
> +  This method returns a row from a tablespace information_schema view
> +  that matches the tablespace name passed. 
> +
> +  @param[in]     thd           Thread context
> +  @param[in]     is_table_idx  The information schema to search
> +  @param[in]     ts_name       The name of the tablespace to find
> +  @param[out]    datafile      The datafile for the tablespace
> +  @param[out]    comments      The comments for the tablespace
> +  
> +  @retval FALSE if tablespace exists and no errors
> +  @retval TRUE if tablespace does not exist or errors
> +*/
> +bool find_tablespace_schema_row(THD *thd,
> +                                enum_schema_tables is_table_idx,
> +                                const String *ts_name,
> +                                String *datafile,
> +                                String *comments)

This helper function should probably be static.

> +{
> +  TABLE *is_table;
> +  handler *ha;
> +  my_bitmap_map *orig_col;
> +  LEX_STRING lex_ts_name;
> +  String found_ts_name;
> +  bool retval= FALSE;
> +  String data;
> +  List<LEX_STRING> ts_list;
> +  DBUG_ENTER("obs::find_tablespace_schema_row()");
> +
> +  /*
> +    First, open the IS table.
> +  */
> +  thd->make_lex_string(&lex_ts_name, ts_name->ptr(),
> +                       ts_name->length(), FALSE);
> +  ts_list.push_back(&lex_ts_name);
> +
> +  if (InformationSchemaIterator::prepare_is_table(
> +      thd, &is_table, &ha, &orig_col, is_table_idx, ts_list))
> +    DBUG_RETURN(TRUE);
> +
> +  /*
> +    Now read from the IS table.
> +  */
> +  if (ha->rnd_next(is_table->record[0]))
> +  {
> +    retval= TRUE;
> +    goto end;
> +  }
> +
> +  /*    
> +    Attempt to locate the row in the tablespaces table.
> +    If found, proceed to the retrieving the data.
> +  */
> +  int ret= 0;
> +  is_table->field[0]->val_str(&found_ts_name);
> +  while (!ret && found_ts_name.length() &&
> +    (strncasecmp(found_ts_name.ptr(), ts_name->ptr(), 
> +     ts_name->length()) != 0))
> +  {
> +    ret= ha->rnd_next(is_table->record[0]);
> +    found_ts_name.length(0); // reset the length of the string
> +    if (!ret)
> +      is_table->field[0]->val_str(&found_ts_name);
> +  }
> +  if (ret || (found_ts_name.length() == 0))
> +  {
> +    retval= TRUE;
> +    goto end;
> +  }
> +
> +  /*
> +    TS name is in col 0 in FALCON_TABLESPACES
> +    TS comment is in col 2 in FALCON_TABLESPACES
> +    TS datafile is in col 3 in FALCON_TABLESPACE_FILES
> +  */
> +  switch (is_table_idx) {
> +    case SCH_FALCON_TABLESPACES:
> +    {
> +      is_table->field[2]->val_str(&data);
> +      comments->copy(data);
> +      break;
> +    }
> +    case SCH_FALCON_TABLESPACE_FILES:
> +    {
> +      is_table->field[3]->val_str(&data);
> +      datafile->copy(data);
> +      break;
> +    }
> +    default:
> +    {
> +      retval= TRUE;  //error
> +      goto end;
> +    }
> +  }
> +  DBUG_PRINT("find_tablespace_schema_row", (" Found tablespace %s", 
> +    found_ts_name.ptr()));
> +
> +  /*
> +    Cleanup
> +  */
> +end:
> +  ha->ha_rnd_end();
> +
> +  dbug_tmp_restore_column_map(is_table->read_set, orig_col);
> +  free_tmp_table(thd, is_table);
> +  DBUG_RETURN(retval);
> +}
> +
> +/**
> +  Build a valid tablespace from the information_schema views.
> +
> +  This method builds a @c TablespaceObj object if the tablespace
> +  exists on the server.
> +
> +  @param[in]     thd           Thread context.
> +  @param[out]    TablespaceObj A pointer to a new tablespace object
> +  @param[in]     ts_name       The name of the tablespace to find
> +  
> +  @note Caller is responsible for destroying the tablespace object.
> +
> +  @retval FALSE if tablespace exists and no errors
> +  @retval TRUE if tablespace does not exist or errors
> +*/
> +bool get_tablespace_from_schema(THD *thd,
> +                                TablespaceObj **ts, 
> +                                const String *ts_name)

This one also static - not a part of public interface.

> +{
> +  String datafile;
> +  String comments;
> +  DBUG_ENTER("obs::get_tablespace_from_schema()");
> +
> +  /*
> +    Locate the row in FALCON_TABLESPACES and get the comments.
> +  */
> +  if (find_tablespace_schema_row(thd, SCH_FALCON_TABLESPACES, 
> +      ts_name, &datafile, &comments))
> +    DBUG_RETURN(TRUE);
> +
> +  /*
> +    Locate the row in FALCON_TABLESPACE_FILES and get the comments.
> +  */
> +  if (find_tablespace_schema_row(thd, SCH_FALCON_TABLESPACE_FILES, 
> +      ts_name, &datafile, &comments))
> +    DBUG_RETURN(TRUE);
> +
> +  /*
> +    The datafile parameter is required.
> +  */
> +  if (datafile.length() == 0)
> +    DBUG_RETURN(TRUE);
> +
> +  DBUG_PRINT("get_tablespace_from_schema", (" Found tablespace %s %s", 
> +    ts_name->ptr(), datafile.ptr()));
> +
> +  TablespaceObj *ts_local= new TablespaceObj(ts_name);
> +  *ts= ts_local;
> +  ts_local->set_datafile(&datafile);
> +  ts_local->set_comments(&comments);
> +
> +  DBUG_RETURN(FALSE);
> +}
> +
> +/**
> +  Retrieve the tablespace for a table if it exists
> +  
> +  This method returns a @c TablespaceObj object if the table has a tablespace.
> +
> +  @param[in]  thd       Thread context.
> +  @param[in]  db_name   The database name for the table.
> +  @param[in]  tbl_name  The table name.
> +  
> +  @note Caller is responsible for destroying the object.
> +
> +  @retval Tablespace object if table uses a tablespace 
> +  @retval NULL if table does not use a tablespace
> +*/
> +Obj *get_tablespace_for_table(THD *thd, 
> +                              const String *db_name, 
> +                              const String *tbl_name)
> +{
> +  bool retval= 0;
> +  TablespaceObj *ts;
> +  LEX_STRING tname, dbname;
> +  String ts_name;
> +  DBUG_ENTER("obs::get_tablespace_for_table()");
> +  DBUG_PRINT("obs::get_tablespace_for_table", ("name: %s.%s", 
> +             db_name, tbl_name));
> +
> +  tname.str= (char *)tbl_name->ptr();
> +  tname.length= tbl_name->length();
> +  dbname.str= (char *)db_name->ptr();
> +  dbname.length= db_name->length();
> +  Table_ident *name_id= new Table_ident(tname);
> +  name_id->db= dbname;
> +
> +  thd->lex->select_lex.add_table_to_list(thd, name_id, NULL, 0);
> +  TABLE_LIST *table_list= (TABLE_LIST*)thd->lex->select_lex.table_list.first;
> +  thd->lex->sql_command = SQLCOM_SHOW_CREATE;
> +
> +  /*
> +    Open the table
> +  */
> +  if (open_normal_and_derived_tables(thd, table_list, 0))
> +    DBUG_RETURN(FALSE);

Please use open_temporary_table() which should be enough for that purpose. When 
a table is opened that way, it must be "closed" with free_tmp_table().

> +
> +  /*
> +    Get the tablespace name and close up shop.
> +  */
> +  TABLE *table= table_list->table;
> +  ts_name.length(0);
> +  if (table->s->db_type()->db_type == DB_TYPE_FALCON)
> +    ts_name.append(table_list->table->file->get_tablespace_name());
> +  else
> +    retval= 1;
> +  close_thread_tables(thd);
> +  ts_name.set_charset(system_charset_info);
> +  thd->lex->select_lex.table_list.empty();
> +  ts= NULL;
> +  if (retval)
> +    goto end;
> +
> +  /*
> +    Now open the information_schema table and get the tablespace information.
> +  */
> +  get_tablespace_from_schema(thd, &ts, &ts_name);
> +
> +end:
> +  DBUG_RETURN(ts);
> +}
> +
> +/**
> +  Determine if tablespace exists.
> +
> +  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 tablespace attributes are different.
> +
> +  @param[in]  Obj  The TablspaceObj pointer to compare.
> +  
> +  @retval TRUE if it exists
> +  @retval FALSE if it does not exist
> +*/
> +bool tablespace_exists(THD *thd,
> +                       Obj *ts)
> +{
> +  TablespaceObj *other_ts= NULL;
> +  bool retval= FALSE;
> +  DBUG_ENTER("obs::tablespace_exists()");
> +  get_tablespace_from_schema(thd, &other_ts, ts->get_name());
> +  if (!other_ts)
> +    DBUG_RETURN(retval);
> +  retval= (my_strcasecmp(system_charset_info, 
> +           other_ts->build_serialization()->ptr(), 
> +           ((TablespaceObj *)ts)->build_serialization()->ptr()) == 0);

I think comparing serialization strings is quite enough for our purposes. 
Especially that you have a full control over the format of CRATE TABLESPACE 
statement.

> +  delete other_ts;
> +  DBUG_RETURN(retval);
> +}
> +
> +/**
> +  Is there a tablespace with the given name?
> +  
> +  This method determines if the tablespace referenced by name exists on the
> +  system.
> +
> +  @param[in]  ts_name  The Tablspace name to compare.
> +  
> +  @retval TRUE if it exists
> +  @retval FALSE if it does not exist
> +*/
> +bool is_tablespace(THD *thd,
> +                   const String *ts_name)
> +{
> +  TablespaceObj *other_ts= NULL;
> +  bool retval= FALSE;
> +  DBUG_ENTER("obs::is_tablespace()");
> +  get_tablespace_from_schema(thd, &other_ts, ts_name);
> +  retval= (other_ts != NULL);
> +  delete other_ts;
> +  DBUG_RETURN(retval);
> +}
> +
> +/**
> +  Decribe a tablespace.
> +
> +  This method returns a description of the tablespace useful for communicating
> +  with the user.
> +
> +  @param[in]  ts  The Tablspace to describe.
> +  
> +  @returns tablespace description
> +*/
> +const String *describe_tablespace(Obj *ts)
> +{
> +  DBUG_ENTER("obs::describe_tablespace()");
> +  DBUG_RETURN(((TablespaceObj *)ts)->describe());
>  }
>  
>  ///////////////////////////////////////////////////////////////////////////
> diff -Nrup a/sql/si_objects.h b/sql/si_objects.h
> --- a/sql/si_objects.h	2008-01-31 10:15:25 -05:00
> +++ b/sql/si_objects.h	2008-04-08 10:57:27 -04:00
> @@ -133,6 +133,9 @@ private:
>                                  uint,
>                                  const String *);
>  
> +  friend Obj *materialize_tablespace(const String *,
> +                                     uint,
> +                                     const String *);
>  };
>  
>  ///////////////////////////////////////////////////////////////////////////
> @@ -445,6 +448,10 @@ Obj *materialize_event(const String *db_
>                         uint serialization_version,
>                         const String *serialialization);
>  
> +Obj *materialize_tablespace(const String *ts_name,
> +                            uint serialization_version,
> +                            const String *serialialization);
> +
>  ///////////////////////////////////////////////////////////////////////////
>  
>  bool is_internal_db_name(const String *db_name);
> @@ -459,6 +466,35 @@ bool is_internal_db_name(const String *d
>      @retval TRUE on error (the database either not exists, or not accessible).
>  */
>  bool check_db_existence(const String *db_name);
> +
> +/*
> +  This method returns a @c TablespaceObj object if the table has a tablespace.
> +*/
> +Obj *get_tablespace_for_table(THD *thd, 
> +                              const String *db_name, 
> +                              const String *tbl_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 tablespace attributes are different.
> +*/
> +bool tablespace_exists(THD *thd,
> +                       Obj *ts);
> +
> +/*
> +  This method determines if the tablespace referenced by name exists on the
> +  system.
> +*/
> +bool is_tablespace(THD *thd,
> +                   const String *ts_name);
> +
> +/*
> +  This method returns a description of the tablespace useful for communicating
> +  with the user.
> +*/
> +const String *describe_tablespace(Obj *ts);
>  
>  ///////////////////////////////////////////////////////////////////////////
>  
> diff -Nrup a/sql/table.h b/sql/table.h
> --- a/sql/table.h	2008-04-01 09:44:55 -04:00
> +++ b/sql/table.h	2008-04-08 10:57:28 -04:00
> @@ -749,7 +749,9 @@ enum enum_schema_tables
>    SCH_TRIGGERS,
>    SCH_USER_PRIVILEGES,
>    SCH_VARIABLES,
> -  SCH_VIEWS
> +  SCH_VIEWS,
> +  SCH_FALCON_TABLESPACES,
> +  SCH_FALCON_TABLESPACE_FILES
>  };
>  
>  
> 
> 
Thread
bk commit into 6.0 tree (cbell:1.2607) WL#4342cbell8 Apr
  • Re: bk commit into 6.0 tree (cbell:1.2607) WL#4342Rafal Somla8 Apr