~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/identifier/table.cc

  • Committer: Lee Bieber
  • Date: 2010-11-14 23:15:42 UTC
  • mfrom: (1929.1.42 warning-stack-frame)
  • Revision ID: kalebral@gmail.com-20101114231542-fnnu6ydd2p17n582
Merge Monty - fix bug 672372: some functions use > 32k stack

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2009 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
23
23
#include <assert.h>
24
24
#include <boost/lexical_cast.hpp>
25
25
#include "drizzled/identifier.h"
 
26
#include "drizzled/session.h"
26
27
#include "drizzled/internal/my_sys.h"
27
28
 
28
 
#include <drizzled/error.h>
29
 
#include <drizzled/errmsg_print.h>
30
 
#include <drizzled/gettext.h>
31
 
 
32
 
#include <drizzled/table.h>
 
29
#include "drizzled/table.h"
33
30
 
34
31
#include "drizzled/util/string.h"
35
32
#include "drizzled/util/tablename_to_filename.h"
45
42
namespace drizzled
46
43
{
47
44
 
48
 
class Table;
49
 
 
50
45
extern std::string drizzle_tmpdir;
51
46
extern pid_t current_pid;
52
47
 
53
 
namespace identifier {
54
 
class Schema;
55
 
 
56
48
static const char hexchars[]= "0123456789abcdef";
57
49
 
58
50
/*
67
59
  RETURN
68
60
    Table name length.
69
61
*/
70
 
uint32_t Table::filename_to_tablename(const char *from, char *to, uint32_t to_length)
 
62
uint32_t TableIdentifier::filename_to_tablename(const char *from, char *to, uint32_t to_length)
71
63
{
72
64
  uint32_t length= 0;
73
65
 
145
137
 
146
138
#endif
147
139
 
148
 
size_t Table::build_tmptable_filename(std::string &buffer)
 
140
size_t TableIdentifier::build_tmptable_filename(std::string &buffer)
149
141
{
150
142
  size_t tmpdir_length;
151
143
  ostringstream post_tmpdir_str;
163
155
  return buffer.length();
164
156
}
165
157
 
166
 
size_t Table::build_tmptable_filename(std::vector<char> &buffer)
 
158
size_t TableIdentifier::build_tmptable_filename(std::vector<char> &buffer)
167
159
{
168
160
  ostringstream post_tmpdir_str;
169
161
 
210
202
    path length on success, 0 on failure
211
203
*/
212
204
 
213
 
size_t Table::build_table_filename(std::string &in_path, const std::string &in_db, const std::string &in_table_name, bool is_tmp)
 
205
size_t TableIdentifier::build_table_filename(std::string &in_path, const std::string &in_db, const std::string &in_table_name, bool is_tmp)
214
206
{
215
207
  bool conversion_error= false;
216
208
 
217
209
  conversion_error= util::tablename_to_filename(in_db, in_path);
218
210
  if (conversion_error)
219
211
  {
220
 
    errmsg_printf(error::ERROR,
 
212
    errmsg_printf(ERRMSG_LVL_ERROR,
221
213
                  _("Schema name cannot be encoded and fit within filesystem "
222
214
                    "name length restrictions."));
223
215
    return 0;
234
226
    conversion_error= util::tablename_to_filename(in_table_name, in_path);
235
227
    if (conversion_error)
236
228
    {
237
 
      errmsg_printf(error::ERROR,
 
229
      errmsg_printf(ERRMSG_LVL_ERROR,
238
230
                    _("Table name cannot be encoded and fit within filesystem "
239
231
                      "name length restrictions."));
240
232
      return 0;
244
236
  return in_path.length();
245
237
}
246
238
 
247
 
Table::Table(const drizzled::Table &table) :
248
 
  identifier::Schema(table.getShare()->getSchemaName()),
 
239
TableIdentifier::TableIdentifier(const drizzled::Table &table) :
 
240
  SchemaIdentifier(table.getShare()->getSchemaName()),
249
241
  type(table.getShare()->getTableType()),
250
242
  table_name(table.getShare()->getTableName())
251
243
{
255
247
  init();
256
248
}
257
249
 
258
 
void Table::init()
 
250
void TableIdentifier::init()
259
251
{
260
252
  switch (type) {
261
253
  case message::Table::FUNCTION:
275
267
    break;
276
268
  }
277
269
 
278
 
  switch (type) {
279
 
  case message::Table::FUNCTION:
280
 
  case message::Table::STANDARD:
281
 
  case message::Table::INTERNAL:
282
 
    break;
283
 
  case message::Table::TEMPORARY:
284
 
    {
285
 
      size_t pos;
286
 
 
287
 
      pos= path.find("tmp/#sql");
288
 
      if (pos != std::string::npos) 
289
 
      {
290
 
        key_path= path.substr(pos);
291
 
      }
292
 
    }
293
 
    break;
294
 
  }
295
 
 
296
270
  util::insensitive_hash hasher;
297
271
  hash_value= hasher(path);
298
272
 
299
 
  std::string tb_name(getTableName());
300
 
  std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
301
 
 
302
 
  key.set(getKeySize(), getSchemaName(), tb_name);
 
273
  key.set(getKeySize(), getSchemaName(), getTableName());
303
274
}
304
275
 
305
276
 
306
 
const std::string &Table::getPath() const
 
277
const std::string &TableIdentifier::getPath() const
307
278
{
308
279
  return path;
309
280
}
310
281
 
311
 
const std::string &Table::getKeyPath() const
312
 
{
313
 
  if (key_path.empty())
314
 
    return path;
315
 
 
316
 
  return key_path;
317
 
}
318
 
 
319
 
void Table::getSQLPath(std::string &sql_path) const  // @todo this is just used for errors, we should find a way to optimize it
320
 
{
321
 
  switch (type) {
322
 
  case message::Table::FUNCTION:
323
 
  case message::Table::STANDARD:
324
 
    sql_path.append(getSchemaName());
325
 
    sql_path.append(".");
326
 
    sql_path.append(table_name);
327
 
    break;
328
 
  case message::Table::INTERNAL:
329
 
    sql_path.append("temporary.");
330
 
    sql_path.append(table_name);
331
 
    break;
332
 
  case message::Table::TEMPORARY:
333
 
    sql_path.append(getSchemaName());
334
 
    sql_path.append(".#");
335
 
    sql_path.append(table_name);
336
 
    break;
337
 
  }
338
 
}
339
 
 
340
 
bool Table::isValid() const
341
 
{
342
 
  if (not identifier::Schema::isValid())
343
 
    return false;
344
 
 
345
 
  bool error= false;
346
 
  do
347
 
  {
348
 
    if (table_name.empty())
349
 
    {
350
 
      error= true;
351
 
      break;
352
 
    }
353
 
 
354
 
    if (table_name.size() > NAME_LEN)
355
 
    {
356
 
      error= true;
357
 
      break;
358
 
    }
359
 
 
360
 
    if (table_name.at(table_name.length() -1) == ' ')
361
 
    {
362
 
      error= true;
363
 
      break;
364
 
    }
365
 
 
366
 
    if (table_name.at(0) == '.')
367
 
    {
368
 
      error= true;
369
 
      break;
370
 
    }
371
 
 
372
 
    {
373
 
      const CHARSET_INFO * const cs= &my_charset_utf8mb4_general_ci;
374
 
 
375
 
      int well_formed_error;
376
 
      uint32_t res= cs->cset->well_formed_len(cs, table_name.c_str(), table_name.c_str() + table_name.length(),
377
 
                                              NAME_CHAR_LEN, &well_formed_error);
378
 
      if (well_formed_error or table_name.length() != res)
379
 
      {
380
 
        error= true;
381
 
        break;
382
 
      }
383
 
    }
384
 
  } while (0);
385
 
 
386
 
  if (error)
387
 
  {
388
 
    std::string name;
389
 
 
390
 
    getSQLPath(name);
391
 
    my_error(ER_WRONG_TABLE_NAME, MYF(0), name.c_str());
392
 
 
393
 
    return false;
394
 
  }
395
 
 
396
 
  return true;
397
 
}
398
 
 
399
 
 
400
 
void Table::copyToTableMessage(message::Table &message) const
 
282
const std::string &TableIdentifier::getSQLPath()  // @todo this is just used for errors, we should find a way to optimize it
 
283
{
 
284
  if (sql_path.empty())
 
285
  {
 
286
    switch (type) {
 
287
    case message::Table::FUNCTION:
 
288
    case message::Table::STANDARD:
 
289
      sql_path.append(getSchemaName());
 
290
      sql_path.append(".");
 
291
      sql_path.append(table_name);
 
292
      break;
 
293
    case message::Table::INTERNAL:
 
294
      sql_path.append("temporary.");
 
295
      sql_path.append(table_name);
 
296
      break;
 
297
    case message::Table::TEMPORARY:
 
298
      sql_path.append(getSchemaName());
 
299
      sql_path.append(".#");
 
300
      sql_path.append(table_name);
 
301
      break;
 
302
    }
 
303
  }
 
304
 
 
305
  return sql_path;
 
306
}
 
307
 
 
308
 
 
309
void TableIdentifier::copyToTableMessage(message::Table &message) const
401
310
{
402
311
  message.set_name(table_name);
403
312
  message.set_schema(getSchemaName());
404
313
}
405
314
 
406
 
void Table::Key::set(size_t resize_arg, const std::string &a, const std::string &b)
 
315
void TableIdentifier::Key::set(size_t resize_arg, const std::string &a, const std::string &b)
407
316
{
408
317
  key_buffer.resize(resize_arg);
409
318
 
414
323
  hash_value= hasher(key_buffer);
415
324
}
416
325
 
417
 
std::size_t hash_value(Table const& b)
418
 
{
419
 
  return b.getHashValue();
420
 
}
421
 
 
422
 
std::size_t hash_value(Table::Key const& b)
423
 
{
424
 
  return b.getHashValue();
425
 
}
426
 
 
427
 
 
428
 
std::ostream& operator<<(std::ostream& output, Table::const_reference identifier)
429
 
{
430
 
  output << "Table:(";
431
 
  output <<  identifier.getSchemaName();
432
 
  output << ", ";
433
 
  output << identifier.getTableName();
434
 
  output << ", ";
435
 
  output << message::type(identifier.getType());
436
 
  output << ", ";
437
 
  output << identifier.getPath();
438
 
  output << ", ";
439
 
  output << identifier.getHashValue();
440
 
  output << ")";
441
 
 
442
 
  return output;  // for multiple << operators.
443
 
}
444
 
 
445
 
} /* namespace identifier */
 
326
std::size_t hash_value(TableIdentifier const& b)
 
327
{
 
328
  return b.getHashValue();
 
329
}
 
330
 
 
331
std::size_t hash_value(TableIdentifier::Key const& b)
 
332
{
 
333
  return b.getHashValue();
 
334
}
 
335
 
446
336
} /* namespace drizzled */