~drizzle-trunk/drizzle/development

1223.4.18 by Brian Aker
More TableIdentifier code.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2009 Sun Microsystems, Inc.
1223.4.18 by Brian Aker
More TableIdentifier code.
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
21
#include <config.h>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
22
23
#include <assert.h>
1775.5.1 by earney
modified files containing stringstream to use boost:lexical_cast instead as
24
#include <boost/lexical_cast.hpp>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
25
#include <drizzled/identifier.h>
26
#include <drizzled/internal/my_sys.h>
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
27
2087.4.1 by Brian Aker
Merge in schema identifier.
28
#include <drizzled/error.h>
29
#include <drizzled/errmsg_print.h>
30
#include <drizzled/gettext.h>
31
32
#include <drizzled/table.h>
1417 by Brian Aker
Interface for Stewart.
33
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
34
#include <drizzled/util/string.h>
35
#include <drizzled/util/tablename_to_filename.h>
1669.3.7 by Brian Aker
Use different hash now for identifier.
36
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
37
#include <algorithm>
38
#include <sstream>
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
39
#include <cstdio>
1223.4.18 by Brian Aker
More TableIdentifier code.
40
1602 by Brian Aker
Update for current_session removal.
41
#include <boost/thread.hpp>
42
1223.4.18 by Brian Aker
More TableIdentifier code.
43
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
44
2252.1.20 by Olaf van der Spek
Common fwd
45
namespace drizzled {
2087.4.1 by Brian Aker
Merge in schema identifier.
46
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
47
extern std::string drizzle_tmpdir;
48
extern pid_t current_pid;
49
2087.4.1 by Brian Aker
Merge in schema identifier.
50
namespace identifier {
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
51
52
static const char hexchars[]= "0123456789abcdef";
53
54
/*
55
  Translate a cursor name to a table name (WL #1324).
56
57
  SYNOPSIS
58
    filename_to_tablename()
59
      from                      The cursor name
60
      to                OUT     The table name
61
      to_length                 The size of the table name buffer.
62
63
  RETURN
64
    Table name length.
65
*/
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
66
uint32_t Table::filename_to_tablename(const char *from, char *to, uint32_t to_length)
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
67
{
68
  uint32_t length= 0;
69
70
  if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
71
  {
72
    /* Temporary table name. */
73
    length= strlen(strncpy(to, from, to_length));
74
  }
75
  else
76
  {
77
    for (; *from  && length < to_length; length++, from++)
78
    {
79
      if (*from != '@')
80
      {
81
        to[length]= *from;
82
        continue;
83
      }
84
      /* We've found an escaped char - skip the @ */
85
      from++;
86
      to[length]= 0;
87
      /* There will be a two-position hex-char version of the char */
88
      for (int x=1; x >= 0; x--)
89
      {
90
        if (*from >= '0' && *from <= '9')
91
          to[length] += ((*from++ - '0') << (4 * x));
92
        else if (*from >= 'a' && *from <= 'f')
93
          to[length] += ((*from++ - 'a' + 10) << (4 * x));
94
      }
95
      /* Backup because we advanced extra in the inner loop */
96
      from--;
97
    } 
98
  }
99
100
  return length;
101
}
102
103
/*
104
  Creates path to a cursor: drizzle_tmpdir/#sql1234_12_1.ext
105
106
  SYNOPSIS
107
   build_tmptable_filename()
108
     session                    The thread handle.
109
     buff                       Where to write result
110
     bufflen                    buff size
111
112
  NOTES
113
114
    Uses current_pid, thread_id, and tmp_table counter to create
115
    a cursor name in drizzle_tmpdir.
116
117
  RETURN
118
    path length on success, 0 on failure
119
*/
120
1602 by Brian Aker
Update for current_session removal.
121
#ifdef _GLIBCXX_HAVE_TLS 
122
__thread uint32_t counter= 0;
123
124
static uint32_t get_counter()
125
{
126
  return ++counter;
127
}
128
129
#else
130
boost::mutex counter_mutex;
131
static uint32_t counter= 1;
132
133
static uint32_t get_counter()
134
{
135
  boost::mutex::scoped_lock lock(counter_mutex);
136
  uint32_t x;
137
  x= ++counter;
138
139
  return x;
140
}
141
142
#endif
143
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
144
size_t Table::build_tmptable_filename(std::string &buffer)
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
145
{
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
146
  size_t tmpdir_length;
147
  ostringstream post_tmpdir_str;
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
148
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
149
  buffer.append(drizzle_tmpdir);
150
  tmpdir_length= buffer.length();
151
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
152
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
153
  post_tmpdir_str << pthread_self() << "-" << get_counter();
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
154
155
  buffer.append(post_tmpdir_str.str());
156
157
  transform(buffer.begin() + tmpdir_length, buffer.end(), buffer.begin() + tmpdir_length, ::tolower);
158
159
  return buffer.length();
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
160
}
161
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
162
size_t Table::build_tmptable_filename(std::vector<char> &buffer)
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
163
{
164
  ostringstream post_tmpdir_str;
165
166
  post_tmpdir_str << drizzle_tmpdir << "/" << TMP_FILE_PREFIX << current_pid;
167
  post_tmpdir_str << pthread_self() << "-" << get_counter();
168
169
  buffer.resize(post_tmpdir_str.str().length() + 1);
170
  memcpy(&buffer[0], post_tmpdir_str.str().c_str(), post_tmpdir_str.str().size());
171
  buffer[post_tmpdir_str.str().size()]= 0;
172
173
  return buffer.size();
174
}
175
176
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
177
/*
178
  Creates path to a cursor: drizzle_data_dir/db/table.ext
179
180
  SYNOPSIS
181
   build_table_filename()
182
     buff                       Where to write result
183
                                This may be the same as table_name.
184
     bufflen                    buff size
185
     db                         Database name
186
     table_name                 Table name
187
     ext                        File extension.
1481 by Brian Aker
Remove dead code.
188
     flags                      table_name is temporary, do not change.
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
189
190
  NOTES
191
192
    Uses database and table name, and extension to create
193
    a cursor name in drizzle_data_dir. Database and table
194
    names are converted from system_charset_info into "fscs".
195
    Unless flags indicate a temporary table name.
196
    'db' is always converted.
197
    'ext' is not converted.
198
199
    The conversion suppression is required for ALTER Table. This
200
    statement creates intermediate tables. These are regular
201
    (non-temporary) tables with a temporary name. Their path names must
202
    be derivable from the table name. So we cannot use
203
    build_tmptable_filename() for them.
204
205
  RETURN
206
    path length on success, 0 on failure
207
*/
208
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
209
size_t Table::build_table_filename(std::string &in_path, const std::string &in_db, const std::string &in_table_name, bool is_tmp)
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
210
{
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
211
  if (util::tablename_to_filename(in_db, in_path))
1864.3.9 by Brian Aker
Remove a couple of memset and now just build the table name in the string of
212
  {
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
213
    errmsg_printf(error::ERROR, _("Schema name cannot be encoded and fit within filesystem name length restrictions."));
1864.3.9 by Brian Aker
Remove a couple of memset and now just build the table name in the string of
214
    return 0;
215
  }
216
1891.2.1 by Monty Taylor
Fixed things to make things compile with clang
217
  in_path.append(FN_ROOTDIR);
1864.3.9 by Brian Aker
Remove a couple of memset and now just build the table name in the string of
218
1481 by Brian Aker
Remove dead code.
219
  if (is_tmp) // It a conversion tmp
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
220
  {
1891.2.1 by Monty Taylor
Fixed things to make things compile with clang
221
    in_path.append(in_table_name);
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
222
  }
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
223
  else if (util::tablename_to_filename(in_table_name, in_path))
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
224
  {
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
225
    errmsg_printf(error::ERROR, _("Table name cannot be encoded and fit within filesystem name length restrictions."));
226
    return 0;
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
227
  }
228
   
1891.2.1 by Monty Taylor
Fixed things to make things compile with clang
229
  return in_path.length();
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
230
}
231
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
232
Table::Table(const drizzled::Table &table) :
2087.4.1 by Brian Aker
Merge in schema identifier.
233
  identifier::Schema(table.getShare()->getSchemaName()),
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
234
  type(table.getShare()->getTableType()),
235
  table_name(table.getShare()->getTableName())
1417 by Brian Aker
Interface for Stewart.
236
{
237
  if (type == message::Table::TEMPORARY)
1574 by Brian Aker
Rollup patch for hiding tableshare.
238
    path= table.getShare()->getPath();
1417 by Brian Aker
Interface for Stewart.
239
240
  init();
241
}
242
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
243
void Table::init()
1395.1.6 by Brian Aker
Modified TableIdentifier output for errors.
244
{
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
245
  switch (type) {
246
  case message::Table::FUNCTION:
247
  case message::Table::STANDARD:
1626.3.3 by Brian Aker
Additional checks on path.
248
    assert(path.size() == 0);
1864.3.9 by Brian Aker
Remove a couple of memset and now just build the table name in the string of
249
    build_table_filename(path, getSchemaName(), table_name, false);
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
250
    break;
251
  case message::Table::INTERNAL:
1626.3.3 by Brian Aker
Additional checks on path.
252
    assert(path.size() == 0);
1864.3.9 by Brian Aker
Remove a couple of memset and now just build the table name in the string of
253
    build_table_filename(path, getSchemaName(), table_name, true);
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
254
    break;
255
  case message::Table::TEMPORARY:
256
    if (path.empty())
257
    {
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
258
      build_tmptable_filename(path);
1223.4.18 by Brian Aker
More TableIdentifier code.
259
    }
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
260
    break;
1223.4.18 by Brian Aker
More TableIdentifier code.
261
  }
262
2139.3.2 by Brian Aker
Fix innodb to just directly use the identifier (this way we only need to
263
  switch (type) {
264
  case message::Table::FUNCTION:
265
  case message::Table::STANDARD:
266
  case message::Table::INTERNAL:
267
    break;
268
  case message::Table::TEMPORARY:
269
    {
270
      size_t pos;
271
272
      pos= path.find("tmp/#sql");
273
      if (pos != std::string::npos) 
274
      {
275
        key_path= path.substr(pos);
276
      }
277
    }
278
    break;
279
  }
280
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
281
  hash_value= util::insensitive_hash()(path);
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
282
1937.4.1 by Andrew Hutchings
Make mixed case table names work again
283
  std::string tb_name(getTableName());
284
  std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
285
286
  key.set(getKeySize(), getSchemaName(), tb_name);
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
287
}
288
289
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
290
const std::string &Table::getPath() const
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
291
{
1358.1.9 by Brian Aker
Update for std::string
292
  return path;
1223.4.18 by Brian Aker
More TableIdentifier code.
293
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
294
2139.3.2 by Brian Aker
Fix innodb to just directly use the identifier (this way we only need to
295
const std::string &Table::getKeyPath() const
296
{
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
297
  return key_path.empty() ? path : key_path;
2139.3.2 by Brian Aker
Fix innodb to just directly use the identifier (this way we only need to
298
}
299
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
300
std::string Table::getSQLPath() const  // @todo this is just used for errors, we should find a way to optimize it
1395.1.6 by Brian Aker
Modified TableIdentifier output for errors.
301
{
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
302
  switch (type) 
303
	{
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
304
  case message::Table::FUNCTION:
305
  case message::Table::STANDARD:
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
306
		return getSchemaName() + "." + table_name;
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
307
  case message::Table::INTERNAL:
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
308
		return "temporary." + table_name;
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
309
  case message::Table::TEMPORARY:
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
310
    return getSchemaName() + ".#" + table_name;
1395.1.6 by Brian Aker
Modified TableIdentifier output for errors.
311
  }
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
312
	assert(false);
313
	return "<no table>";
1395.1.6 by Brian Aker
Modified TableIdentifier output for errors.
314
}
315
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
316
bool Table::isValid() const
1992.4.1 by Brian Aker
Update code for testing identifiers/table/schema name correctness.
317
{
2087.4.1 by Brian Aker
Merge in schema identifier.
318
  if (not identifier::Schema::isValid())
1992.4.1 by Brian Aker
Update code for testing identifiers/table/schema name correctness.
319
    return false;
320
321
  bool error= false;
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
322
  if (table_name.empty()
323
		|| table_name.size() > NAME_LEN
324
		|| table_name[table_name.length() - 1] == ' '
325
		|| table_name[0] == '.')
326
  {
327
    error= true;
328
  }
329
	else
330
  {
331
    int well_formed_error;
332
    uint32_t res= my_charset_utf8mb4_general_ci.cset->well_formed_len(&my_charset_utf8mb4_general_ci, 
333
			table_name.c_str(), table_name.c_str() + table_name.length(), NAME_CHAR_LEN, &well_formed_error);
334
    if (well_formed_error or table_name.length() != res)
335
      error= true;
336
  }
337
  if (not error)
338
		return true;
339
  my_error(ER_WRONG_TABLE_NAME, MYF(0), getSQLPath().c_str());
340
  return false;
1992.4.1 by Brian Aker
Update code for testing identifiers/table/schema name correctness.
341
}
342
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
343
void Table::copyToTableMessage(message::Table &message) const
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
344
{
345
  message.set_name(table_name);
1415 by Brian Aker
Mass overhaul to use schema_identifier.
346
  message.set_schema(getSchemaName());
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
347
}
348
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
349
void Table::Key::set(size_t resize_arg, const std::string &a, const std::string &b)
1878.5.3 by Brian Aker
Update Key to work a bit faster.
350
{
351
  key_buffer.resize(resize_arg);
352
353
  std::copy(a.begin(), a.end(), key_buffer.begin());
354
  std::copy(b.begin(), b.end(), key_buffer.begin() + a.length() + 1);
355
356
  util::sensitive_hash hasher;
357
  hash_value= hasher(key_buffer);
358
}
359
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
360
std::size_t hash_value(Table const& b)
361
{
362
  return b.getHashValue();
363
}
364
365
std::size_t hash_value(Table::Key const& b)
366
{
367
  return b.getHashValue();
368
}
369
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
370
std::ostream& operator<<(std::ostream& output, const Table& identifier)
2134.1.7 by Brian Aker
Collapse strings used for table.
371
{
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
372
  return output << "Table:(" <<  identifier.getSchemaName() << ", " << identifier.getTableName() << ", " << message::type(identifier.getType()) << ", " << identifier.getPath() << ", " << identifier.getHashValue() << ")";
2134.1.7 by Brian Aker
Collapse strings used for table.
373
}
374
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
375
} /* namespace identifier */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
376
} /* namespace drizzled */