List:Commits« Previous MessageNext Message »
From:rsomla Date:January 10 2008 7:36pm
Subject:bk commit into 6.0 tree (rafal:1.2759)
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of rafal. When rafal 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-01-10 20:36:04+01:00, rafal@quant.(none) +2 -0
  Implementation of enumeration services for databases, tables and views. This uses the 
  code which was previously used inside the backup kernel.

  sql/backup/si_objects.cc@stripped, 2008-01-10 20:36:01+01:00, rafal@quant.(none) +240 -0
    Added implementation of get_databases, get_tables and get_views functions.

  sql/backup/si_objects.h@stripped, 2008-01-10 20:36:01+01:00, rafal@quant.(none) +3 -3
    Current implementation of enumeration functions needs THD context to work
    - added it to signature.

diff -Nrup a/sql/backup/si_objects.cc b/sql/backup/si_objects.cc
--- a/sql/backup/si_objects.cc	2008-01-10 02:31:20 +01:00
+++ b/sql/backup/si_objects.cc	2008-01-10 20:36:01 +01:00
@@ -14,3 +14,243 @@
  */ 
 
 #include "si_objects.h"
+
+#define ERROR 1
+
+TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list); // defined in sql_show.cc
+static TABLE* open_schema_table(THD *thd, ST_SCHEMA_TABLE *st);
+
+
+int get_databases(THD *thd, DYNAMIC_ARRAY *dbs)
+{
+  /*
+    This implementation reads INFORMATION_SCHEMA.SCHEMATA table to get
+    all database names. This is ad-hoc implementation. Feel free to change and/or 
+    improve it as you like (/Rafal)
+    
+    TODO: share code with SHOW DATABASES implementation.
+   */
+
+  my_bitmap_map *old_map;
+
+  DBUG_ENTER("get_databases");
+
+  if (my_init_dynamic_array(dbs,sizeof(LEX_STRING),0,100))
+    DBUG_RETURN(ERROR);
+
+  TABLE *db_table = open_schema_table(thd, ::get_schema_table(SCH_SCHEMATA));
+
+  if (!db_table)
+    DBUG_RETURN(ERROR);
+
+  handler *ha = db_table->file;
+  int res= 0;
+
+  old_map= dbug_tmp_use_all_columns(db_table, db_table->read_set);
+
+  if (ha->ha_rnd_init(TRUE))
+  {
+    res= ERROR;
+    goto finish;
+  }
+
+  while (!ha->rnd_next(db_table->record[0]))
+  {
+    String buf;
+    LEX_STRING db_name;
+
+    db_table->field[1]->val_str(&buf);
+
+    DBUG_PRINT("get_database", (" Found database %s", buf.ptr()));
+
+    db_name.str= sql_strmake(buf.ptr(), buf.length());
+    db_name.length= buf.length();
+    
+    if (insert_dynamic(dbs, (uchar*)&db_name))
+    {
+      res= ERROR;
+      goto finish;
+    }    
+  }
+
+  DBUG_PRINT("get_database", ("No more databases in I_S"));
+
+  ha->ha_rnd_end();
+
+ finish:
+
+  if (db_table)
+  {
+    dbug_tmp_restore_column_map(db_table->read_set, old_map);
+    ::free_tmp_table(thd, db_table);
+  }
+
+  DBUG_RETURN(res);
+}
+
+/**
+  List tables or views in a given database.
+*/ 
+static
+int get_tables_or_views(THD *thd, LEX_STRING db, bool get_views, 
+                        DYNAMIC_ARRAY *tables)
+{
+  /*
+    This is implemented by iterating over contents of 
+    INFORMATION_SCHEMA.TABLES table which does not contain entries
+    for the INFORMATION_SCHEMA database itself. That means tha we 
+    can't list tables or views inside INFORMATION_SCHEMA database (which
+    is not a problem for the moment).
+    
+    This is ad-hoc implementation. Feel free to change and/or 
+    improve it as you like (/Rafal)
+    
+    TODO: share code with SHOW TABLES/VIEWS implementation.
+   */
+
+  my_bitmap_map *old_map;
+
+  DBUG_ENTER("get_tables");
+
+  if (my_init_dynamic_array(tables,sizeof(LEX_STRING),0,100))
+    DBUG_RETURN(ERROR);
+
+  TABLE *i_s_tables = open_schema_table(thd, ::get_schema_table(SCH_TABLES));
+
+  if (!i_s_tables)
+    DBUG_RETURN(ERROR);
+
+  handler *ha= i_s_tables->file;
+
+  old_map= dbug_tmp_use_all_columns(i_s_tables, i_s_tables->read_set);
+
+  if (ha->ha_rnd_init(TRUE))
+  {
+    dbug_tmp_restore_column_map(i_s_tables->read_set, old_map);
+    return ERROR;
+  }
+
+  int res= 0;
+
+  String db_name(db.str,db.length,system_charset_info);
+
+  /*
+   TODO: Instead of looping through all records in the I_S.TABLES table
+   it would be better to execute an SQL query with appropriate WHERE clause.
+  */
+  while (!ha->rnd_next(i_s_tables->record[0]))
+  {
+    String table_db;
+    String table_type;
+    String table_name;
+    LEX_STRING name;
+
+    /*
+      Read info about next table/view
+
+      Note: this should be synchronized with the definition of
+      INFORMATION_SCHEMA.TABLES table.
+     */
+    i_s_tables->field[1]->val_str(&table_db);
+    i_s_tables->field[2]->val_str(&table_name);
+    i_s_tables->field[3]->val_str(&table_type);
+
+    // skip tables not from the given database
+    if (table_db != db_name)
+      continue;
+
+    // FIXME: right now, we handle only tables
+    bool correct_type = 
+      get_views ? table_type == String("VIEW", system_charset_info) :
+                  table_type == String("BASE TABLE", system_charset_info);
+    if (!correct_type)  
+      continue;
+
+    DBUG_PRINT("get_tables", ("Found table %s in database %s",
+                               table_name.ptr(), table_db.ptr()));
+
+    name.str= sql_strmake(table_name.ptr(), table_name.length());
+    name.length= table_name.length();
+    
+    if (insert_dynamic(tables, (uchar*)&name))
+    {
+      res= ERROR;
+      goto error;
+    }    
+  }
+
+  goto finish;
+
+ error:
+
+  res= res ? res : ERROR;
+
+ finish:
+
+  ha->ha_rnd_end();
+
+  dbug_tmp_restore_column_map(i_s_tables->read_set, old_map);
+
+  return res;
+}
+
+int get_tables(THD *thd, LEX_STRING db, DYNAMIC_ARRAY *tables)
+{
+  return get_tables_or_views(thd,db,FALSE,tables);
+}
+
+int get_views(THD *thd, LEX_STRING db, DYNAMIC_ARRAY *views)
+{
+  return get_tables_or_views(thd,db,TRUE,views);
+}
+
+
+/** 
+  Open given table in @c INFORMATION_SCHEMA database.
+*/
+TABLE* open_schema_table(THD *thd, ST_SCHEMA_TABLE *st)
+{
+  TABLE *t;
+  TABLE_LIST arg;
+  my_bitmap_map *old_map;
+
+  bzero( &arg, sizeof(TABLE_LIST) );
+
+  // set context for create_schema_table call
+  arg.schema_table= st;
+  arg.alias=        NULL;
+  arg.select_lex=   NULL;
+
+  t= create_schema_table(thd,&arg); // Note: callers must free t.
+
+  if( !t ) return NULL; // error!
+
+  /*
+   Temporarily set thd->lex->wild to NULL to keep st->fill_table
+   happy.
+  */
+  String *wild= thd->lex->wild;
+  enum_sql_command command= thd->lex->sql_command;
+
+  thd->lex->wild = NULL;
+  thd->lex->sql_command = enum_sql_command(0);
+
+  // context for fill_table
+  arg.table= t;
+
+  old_map= tmp_use_all_columns(t, t->read_set);
+
+  /*
+    Question: is it correct to fill I_S table each time we use it or should it
+    be filled only once?
+   */
+  st->fill_table(thd,&arg,NULL);  // NULL = no select condition
+
+  tmp_restore_column_map(t->read_set, old_map);
+
+  // undo changes to thd->lex
+  thd->lex->wild= wild;
+  thd->lex->sql_command= command;
+
+  return t;
+}
diff -Nrup a/sql/backup/si_objects.h b/sql/backup/si_objects.h
--- a/sql/backup/si_objects.h	2008-01-10 02:31:20 +01:00
+++ b/sql/backup/si_objects.h	2008-01-10 20:36:01 +01:00
@@ -223,7 +223,7 @@ int get_create_info_constraint(LEX_STRIN
   
   @return 0 on success, error code if error.
  */
-int get_databases(DYNAMIC_ARRAY *dbs);
+int get_databases(THD *thd, DYNAMIC_ARRAY *dbs);
 
 /**
   List all tables belonging to a given database.
@@ -235,7 +235,7 @@ int get_databases(DYNAMIC_ARRAY *dbs);
 
   @return 0 on success, error code if error.
  */
-int get_tables(LEX_STRING db, DYNAMIC_ARRAY *tables);
+int get_tables(THD *thd, LEX_STRING db, DYNAMIC_ARRAY *tables);
 
 /**
   List all views belonging to a given database.
@@ -245,7 +245,7 @@ int get_tables(LEX_STRING db, DYNAMIC_AR
 
   @return 0 on success, error code if error.
  */
-int get_views(LEX_STRING db, DYNAMIC_ARRAY *views);
+int get_views(THD *thd, LEX_STRING db, DYNAMIC_ARRAY *views);
 
 /**
   List all stored procedures belonging to a given database.
Thread
bk commit into 6.0 tree (rafal:1.2759)rsomla11 Jan