~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/show.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-08-07 14:14:58 UTC
  • mfrom: (1112 staging)
  • mto: (1115.3.4 captain)
  • mto: This revision was merged to the branch mainline in revision 1117.
  • Revision ID: osullivan.padraig@gmail.com-20090807141458-qrc3don58s304ore
MergeĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <drizzled/server_includes.h>
23
23
#include <drizzled/sql_select.h>
24
24
#include <drizzled/show.h>
25
 
#include <mysys/my_dir.h>
26
25
#include <drizzled/gettext.h>
27
26
#include <drizzled/util/convert.h>
28
27
#include <drizzled/error.h>
43
42
#include "drizzled/plugin_registry.h"
44
43
#include <drizzled/info_schema.h>
45
44
#include <drizzled/message/schema.pb.h>
 
45
#include <mysys/cached_directory.h>
 
46
#include <sys/stat.h>
46
47
 
47
48
#include <string>
48
49
#include <iostream>
134
135
  return (*str != '\0');
135
136
}
136
137
 
137
 
/***************************************************************************
138
 
** List all table types supported
139
 
***************************************************************************/
140
 
 
141
138
 
142
139
/**
143
140
 * @brief
144
 
 *   Find files in a given directory.
 
141
 *   Find subdirectories (schemas) in a given directory (datadir).
145
142
 *
146
143
 * @param[in]  session    Thread handler
147
 
 * @param[out] files      Put found files in this list
148
 
 * @param[in]  db         Used in error message when directory is not found
 
144
 * @param[out] files      Put found entries in this list
149
145
 * @param[in]  path       Path to database
150
 
 * @param[in]  wild       Filter for found files
151
 
 * @param[in]  dir        Read databases in path if true, read .frm files in
152
 
 *                        database otherwise
 
146
 * @param[in]  wild       Filter for found entries
153
147
 *
154
 
 * @retval FIND_FILES_OK    Success
155
 
 * @retval FIND_FILES_OOM   Out of memory error
156
 
 * @retval FIND_FILES_DIR   No such directory or directory can't be read
 
148
 * @retval false   Success
 
149
 * @retval true    Error
157
150
 */
158
 
find_files_result find_files(Session *session, vector<LEX_STRING*> &files,
159
 
                             const char *db, const char *path, const char *wild,
160
 
                             bool dir)
 
151
static bool find_schemas(Session *session, vector<LEX_STRING*> &files,
 
152
                         const char *path, const char *wild)
161
153
{
162
154
  if (wild && (wild[0] == '\0'))
163
155
    wild= 0;
164
156
 
165
 
  MY_DIR *dirp= my_dir(path, MYF(dir ? MY_WANT_STAT : 0));
166
 
  if (dirp == NULL)
 
157
  CachedDirectory directory(path);
 
158
 
 
159
  if (directory.fail())
167
160
  {
168
 
    if (my_errno == ENOENT)
169
 
      my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
170
 
    else
171
 
      my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
172
 
 
173
 
    return(FIND_FILES_DIR);
 
161
    my_errno= directory.getError();
 
162
    my_error(ER_CANT_READ_DIR, MYF(0), path, my_errno);
 
163
    return(true);
174
164
  }
175
165
 
176
 
  for (unsigned i= 0; i < dirp->number_off_files; i++)
 
166
  CachedDirectory::Entries entries= directory.getEntries();
 
167
  CachedDirectory::Entries::iterator entry_iter= entries.begin();
 
168
 
 
169
  while (entry_iter != entries.end())
177
170
  {
178
171
    uint32_t file_name_len;
179
172
    char uname[NAME_LEN + 1];                   /* Unencoded name */
180
 
    FILEINFO *file= dirp->dir_entry+i;
181
 
 
182
 
    if (dir)
183
 
    {                                           /* Return databases */
184
 
      if ((file->name[0] == '.' &&
185
 
          ((file->name[1] == '.' && file->name[2] == '\0') ||
186
 
            file->name[1] == '\0')))
187
 
        continue;                               /* . or .. */
188
 
 
189
 
      if (!S_ISDIR(file->mystat->st_mode))
190
 
        continue;
191
 
 
192
 
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
193
 
      if (wild && wild_compare(uname, wild, 0))
194
 
        continue;
195
 
    }
196
 
    else
197
 
    {
198
 
      // Return only .frm files which aren't temp files.
199
 
      char *ext= fn_rext(file->name);
200
 
      if (my_strcasecmp(system_charset_info, ext, ".dfe") ||
201
 
          is_prefix(file->name, TMP_FILE_PREFIX))
202
 
        continue;
203
 
 
204
 
      *ext= 0;
205
 
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
206
 
      if (wild)
207
 
      {
208
 
        if (wild_case_compare(files_charset_info, uname, wild))
209
 
          continue;
210
 
      }
 
173
    struct stat entry_stat;
 
174
    CachedDirectory::Entry *entry= *entry_iter;
 
175
 
 
176
    if ((entry->filename == ".") || (entry->filename == ".."))
 
177
    {
 
178
      ++entry_iter;
 
179
      continue;
 
180
    }
 
181
 
 
182
    if (stat(entry->filename.c_str(), &entry_stat))
 
183
    {
 
184
      my_errno= errno;
 
185
      my_error(ER_CANT_GET_STAT, MYF(0), entry->filename.c_str(), my_errno);
 
186
      return(true);
 
187
    }
 
188
 
 
189
    if (! S_ISDIR(entry_stat.st_mode))
 
190
    {
 
191
      ++entry_iter;
 
192
      continue;
 
193
    }
 
194
 
 
195
    file_name_len= filename_to_tablename(entry->filename.c_str(), uname,
 
196
                                         sizeof(uname));
 
197
    if (wild && wild_compare(uname, wild, 0))
 
198
    {
 
199
      ++entry_iter;
 
200
      continue;
211
201
    }
212
202
 
213
203
    LEX_STRING *file_name= 0;
214
204
    file_name= session->make_lex_string(file_name, uname, file_name_len, true);
215
205
    if (file_name == NULL)
216
 
    {
217
 
      my_dirend(dirp);
218
 
      return(FIND_FILES_OOM);
219
 
    }
 
206
      return(true);
220
207
 
221
208
    files.push_back(file_name);
 
209
    ++entry_iter;
222
210
  }
223
211
 
224
 
  my_dirend(dirp);
225
 
 
226
 
  return(FIND_FILES_OK);
 
212
  return(false);
227
213
}
228
214
 
229
215
 
234
220
  String buffer(buff, sizeof(buff), system_charset_info);
235
221
 
236
222
  /* Only one table for now, but VIEW can involve several tables */
237
 
  if (session->open_normal_and_derived_tables(table_list, 0))
 
223
  if (session->openTables(table_list))
238
224
  {
239
225
    if (session->is_error())
240
226
      return true;
387
373
{
388
374
  Table *table;
389
375
 
390
 
  if (session->open_normal_and_derived_tables(table_list, 0))
 
376
  if (session->openTables(table_list))
391
377
    return;
392
378
  table= table_list->table;
393
379
 
1498
1484
 
1499
1485
 
1500
1486
/**
 
1487
 * Function used for sorting with std::sort within make_db_list.
 
1488
 *
 
1489
 * @returns true if a < b, false otherwise
 
1490
 */
 
1491
 
 
1492
static bool lex_string_sort(const LEX_STRING *a, const LEX_STRING *b)
 
1493
{
 
1494
  return (strcmp(a->str, b->str) < 0);
 
1495
}
 
1496
 
 
1497
 
 
1498
/**
1501
1499
 * @brief
1502
1500
 *   Create db names list. Information schema name always is first in list
1503
1501
 *
1536
1534
      *with_i_schema= 1;
1537
1535
      files.push_back(i_s_name_copy);
1538
1536
    }
1539
 
    return (find_files(session, files, NULL, drizzle_data_home,
1540
 
                       lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
 
1537
 
 
1538
    if (find_schemas(session, files, drizzle_data_home,
 
1539
                     lookup_field_vals->db_value.str) == true)
 
1540
    {
 
1541
      return 1;
 
1542
    }
 
1543
 
 
1544
    sort(files.begin()+1, files.end(), lex_string_sort);
 
1545
    return 0;
1541
1546
  }
1542
1547
 
1543
1548
 
1566
1571
  files.push_back(i_s_name_copy);
1567
1572
 
1568
1573
  *with_i_schema= 1;
1569
 
  return (find_files(session, files, NULL,
1570
 
                     drizzle_data_home, NULL, 1) != FIND_FILES_OK);
 
1574
 
 
1575
  if (find_schemas(session, files, drizzle_data_home, NULL) == true)
 
1576
  {
 
1577
    return 1;
 
1578
  }
 
1579
 
 
1580
  sort(files.begin()+1, files.end(), lex_string_sort);
 
1581
  return 0;
1571
1582
}
1572
1583
 
1573
1584
 
1757
1768
    SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
1758
1769
  */
1759
1770
  lex->sql_command= SQLCOM_SHOW_FIELDS;
1760
 
  res= session->open_normal_and_derived_tables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
 
1771
  res= session->openTables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
1761
1772
  lex->sql_command= save_sql_command;
1762
1773
  /*
1763
1774
    get_all_tables() returns 1 on failure and 0 on success thus
2114
2125
          lex->sql_command= SQLCOM_SHOW_FIELDS;
2115
2126
          show_table_list->i_s_requested_object=
2116
2127
            schema_table->getRequestedObject();
2117
 
          res= session->open_normal_and_derived_tables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
 
2128
          res= session->openTables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
2118
2129
          lex->sql_command= save_sql_command;
2119
2130
          /*
2120
2131
            XXX->  show_table_list has a flag i_is_requested,
2121
 
            and when it's set, open_normal_and_derived_tables()
 
2132
            and when it's set, openTables()
2122
2133
            can return an error without setting an error message
2123
2134
            in Session, which is a hack. This is why we have to
2124
2135
            check for res, then for session->is_error() only then
2723
2734
        table_list->table->file->extra(HA_EXTRA_NO_CACHE);
2724
2735
        table_list->table->file->extra(HA_EXTRA_RESET_STATE);
2725
2736
        table_list->table->file->ha_delete_all_rows();
2726
 
        free_io_cache(table_list->table);
2727
 
        filesort_free_buffers(table_list->table,1);
 
2737
        table_list->table->free_io_cache();
 
2738
        table_list->table->filesort_free_buffers(true);
2728
2739
        table_list->table->null_row= 0;
2729
2740
      }
2730
2741
      else