~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);
2318.9.5 by Olaf van der Spek
Refactor build_table_filename
136
  return ++counter;
1602 by Brian Aker
Update for current_session removal.
137
}
138
139
#endif
140
2318.9.5 by Olaf van der Spek
Refactor build_table_filename
141
std::string Table::build_tmptable_filename()
142
{
143
  ostringstream os;
144
  os << "/" << TMP_FILE_PREFIX << current_pid << pthread_self() << "-" << get_counter();
145
  return drizzle_tmpdir + boost::to_lower_copy(os.str());
146
}
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
147
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
148
/*
149
  Creates path to a cursor: drizzle_data_dir/db/table.ext
150
151
  SYNOPSIS
152
   build_table_filename()
153
     buff                       Where to write result
154
                                This may be the same as table_name.
155
     bufflen                    buff size
156
     db                         Database name
157
     table_name                 Table name
158
     ext                        File extension.
1481 by Brian Aker
Remove dead code.
159
     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
160
161
  NOTES
162
163
    Uses database and table name, and extension to create
164
    a cursor name in drizzle_data_dir. Database and table
165
    names are converted from system_charset_info into "fscs".
166
    Unless flags indicate a temporary table name.
167
    'db' is always converted.
168
    'ext' is not converted.
169
170
    The conversion suppression is required for ALTER Table. This
171
    statement creates intermediate tables. These are regular
172
    (non-temporary) tables with a temporary name. Their path names must
173
    be derivable from the table name. So we cannot use
174
    build_tmptable_filename() for them.
175
176
  RETURN
177
    path length on success, 0 on failure
178
*/
179
2318.9.9 by Olaf van der Spek
Refactor build_table_filename
180
std::string Table::build_table_filename(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
181
{
2318.9.9 by Olaf van der Spek
Refactor build_table_filename
182
  string in_path= util::tablename_to_filename(in_db) + FN_LIBCHAR;
183
  return in_path + (is_tmp ? in_table_name : util::tablename_to_filename(in_table_name));
1309.1.24 by Brian Aker
Moved the build table stuff into table_identifier (all to make it simpler to
184
}
185
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
186
Table::Table(const drizzled::Table &table) :
2440.2.13 by Olaf van der Spek
Refactor
187
  identifier::Schema(str_ref(table.getShare()->getSchemaName())),
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
188
  type(table.getShare()->getTableType()),
189
  table_name(table.getShare()->getTableName())
1417 by Brian Aker
Interface for Stewart.
190
{
191
  if (type == message::Table::TEMPORARY)
1574 by Brian Aker
Rollup patch for hiding tableshare.
192
    path= table.getShare()->getPath();
1417 by Brian Aker
Interface for Stewart.
193
194
  init();
195
}
196
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
197
void Table::init()
1395.1.6 by Brian Aker
Modified TableIdentifier output for errors.
198
{
2318.9.8 by Olaf van der Spek
Refactor tablename_to_filename()
199
  switch (type) 
200
  {
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
201
  case message::Table::FUNCTION:
202
  case message::Table::STANDARD:
2318.9.8 by Olaf van der Spek
Refactor tablename_to_filename()
203
    assert(path.empty());
2318.9.9 by Olaf van der Spek
Refactor build_table_filename
204
    path= build_table_filename(getSchemaName(), table_name, false);
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
205
    break;
206
  case message::Table::INTERNAL:
2318.9.5 by Olaf van der Spek
Refactor build_table_filename
207
    assert(path.empty());
2318.9.9 by Olaf van der Spek
Refactor build_table_filename
208
    path= build_table_filename(getSchemaName(), table_name, true);
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
209
    break;
210
  case message::Table::TEMPORARY:
211
    if (path.empty())
2318.9.5 by Olaf van der Spek
Refactor build_table_filename
212
      path= build_tmptable_filename();
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
213
    break;
1223.4.18 by Brian Aker
More TableIdentifier code.
214
  }
215
2318.9.8 by Olaf van der Spek
Refactor tablename_to_filename()
216
  if (type == message::Table::TEMPORARY)
217
  {
218
    size_t pos= path.find("tmp/#sql");
219
    if (pos != std::string::npos) 
220
      key_path= path.substr(pos);
2139.3.2 by Brian Aker
Fix innodb to just directly use the identifier (this way we only need to
221
  }
222
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
223
  hash_value= util::insensitive_hash()(path);
2478.2.1 by Stewart Smith
ensure that Table::Key has the CATALOG along with SCHEMA and TABLE_NAME in it. Modify the (not so great) code in Table and TableShare to handle this too. This is one of the precursors for proper CATALOG support.
224
  key.set(getKeySize(), getCatalogName(), getSchemaName(), boost::to_lower_copy(std::string(getTableName())));
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
225
}
226
227
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
228
const std::string &Table::getPath() const
1608.2.1 by Brian Aker
Modified to table identifier to fix temporary table creation loss of file.
229
{
1358.1.9 by Brian Aker
Update for std::string
230
  return path;
1223.4.18 by Brian Aker
More TableIdentifier code.
231
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
232
2139.3.2 by Brian Aker
Fix innodb to just directly use the identifier (this way we only need to
233
const std::string &Table::getKeyPath() const
234
{
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
235
  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
236
}
237
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
238
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.
239
{
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
240
  switch (type) 
241
	{
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
242
  case message::Table::FUNCTION:
243
  case message::Table::STANDARD:
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
244
		return getSchemaName() + "." + table_name;
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
245
  case message::Table::INTERNAL:
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
246
		return "temporary." + table_name;
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
247
  case message::Table::TEMPORARY:
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
248
    return getSchemaName() + ".#" + table_name;
1395.1.6 by Brian Aker
Modified TableIdentifier output for errors.
249
  }
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
250
	assert(false);
251
	return "<no table>";
1395.1.6 by Brian Aker
Modified TableIdentifier output for errors.
252
}
253
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
254
bool Table::isValid() const
1992.4.1 by Brian Aker
Update code for testing identifiers/table/schema name correctness.
255
{
2087.4.1 by Brian Aker
Merge in schema identifier.
256
  if (not identifier::Schema::isValid())
1992.4.1 by Brian Aker
Update code for testing identifiers/table/schema name correctness.
257
    return false;
258
259
  bool error= false;
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
260
  if (table_name.empty()
261
		|| table_name.size() > NAME_LEN
262
		|| table_name[table_name.length() - 1] == ' '
263
		|| table_name[0] == '.')
264
  {
265
    error= true;
266
  }
267
	else
268
  {
2440.2.14 by Olaf van der Spek
Refactor
269
    const charset_info_st& cs= my_charset_utf8mb4_general_ci;
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
270
    int well_formed_error;
2440.2.14 by Olaf van der Spek
Refactor
271
    uint32_t res= cs.cset->well_formed_len(cs, table_name, NAME_CHAR_LEN, &well_formed_error);
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
272
    if (well_formed_error or table_name.length() != res)
273
      error= true;
274
  }
275
  if (not error)
276
		return true;
277
  my_error(ER_WRONG_TABLE_NAME, MYF(0), getSQLPath().c_str());
278
  return false;
1992.4.1 by Brian Aker
Update code for testing identifiers/table/schema name correctness.
279
}
280
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
281
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.
282
{
283
  message.set_name(table_name);
1415 by Brian Aker
Mass overhaul to use schema_identifier.
284
  message.set_schema(getSchemaName());
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
285
}
286
2478.2.1 by Stewart Smith
ensure that Table::Key has the CATALOG along with SCHEMA and TABLE_NAME in it. Modify the (not so great) code in Table and TableShare to handle this too. This is one of the precursors for proper CATALOG support.
287
  void Table::Key::set(size_t resize_arg, const std::string &a, const std::string &b, const std::string &c)
1878.5.3 by Brian Aker
Update Key to work a bit faster.
288
{
289
  key_buffer.resize(resize_arg);
290
291
  std::copy(a.begin(), a.end(), key_buffer.begin());
292
  std::copy(b.begin(), b.end(), key_buffer.begin() + a.length() + 1);
2478.2.1 by Stewart Smith
ensure that Table::Key has the CATALOG along with SCHEMA and TABLE_NAME in it. Modify the (not so great) code in Table and TableShare to handle this too. This is one of the precursors for proper CATALOG support.
293
  std::copy(c.begin(), c.end(),
294
            key_buffer.begin() + a.length() + 1 + b.length() + 1);
1878.5.3 by Brian Aker
Update Key to work a bit faster.
295
296
  util::sensitive_hash hasher;
297
  hash_value= hasher(key_buffer);
298
}
299
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
300
std::size_t hash_value(Table const& b)
301
{
302
  return b.getHashValue();
303
}
304
305
std::size_t hash_value(Table::Key const& b)
306
{
307
  return b.getHashValue();
308
}
309
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
310
std::ostream& operator<<(std::ostream& output, const Table& identifier)
2134.1.7 by Brian Aker
Collapse strings used for table.
311
{
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
312
  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.
313
}
314
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
315
} /* namespace identifier */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
316
} /* namespace drizzled */