~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
16
#include <drizzled/server_includes.h>
549 by Monty Taylor
Took gettext.h out of header files.
17
#include <drizzled/error.h>
584.1.13 by Monty Taylor
Split out a little more code. Removed table_list.h from common_includes.
18
#include <drizzled/virtual_column_info.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
19
#include <drizzled/session.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
20
#include <drizzled/unireg.h>
1 by brian
clean slate
21
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
22
/* For proto */
23
#include <string>
24
#include <fstream>
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
25
#include <drizzled/message/schema.pb.h>
26
#include <drizzled/message/table.pb.h>
869.1.2 by Stewart Smith
move to using ZeroCopyInputStream with a file descriptor from open(2) for FRM parsing so we can get errno.
27
#include <google/protobuf/io/zero_copy_stream.h>
28
#include <google/protobuf/io/zero_copy_stream_impl.h>
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
29
using namespace std;
30
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
31
int drizzle_read_table_proto(const char* path, drizzled::message::Table* table)
673.3.12 by Stewart Smith
fix RENAME TABLE
32
{
869.1.2 by Stewart Smith
move to using ZeroCopyInputStream with a file descriptor from open(2) for FRM parsing so we can get errno.
33
  int fd= open(path, O_RDONLY);
34
35
  if(fd==-1)
36
    return errno;
37
38
  google::protobuf::io::ZeroCopyInputStream* input=
39
    new google::protobuf::io::FileInputStream(fd);
40
41
  if (!table->ParseFromZeroCopyStream(input))
820.1.3 by Stewart Smith
remove mysql_frm_type and instead resolve engine from reading proto
42
  {
896.3.10 by Stewart Smith
fix small memory leak in drizzle_read_table_proto: delete input stream
43
    delete input;
869.1.2 by Stewart Smith
move to using ZeroCopyInputStream with a file descriptor from open(2) for FRM parsing so we can get errno.
44
    close(fd);
45
    return -1;
820.1.3 by Stewart Smith
remove mysql_frm_type and instead resolve engine from reading proto
46
  }
869.1.2 by Stewart Smith
move to using ZeroCopyInputStream with a file descriptor from open(2) for FRM parsing so we can get errno.
47
896.3.10 by Stewart Smith
fix small memory leak in drizzle_read_table_proto: delete input stream
48
  delete input;
869.1.2 by Stewart Smith
move to using ZeroCopyInputStream with a file descriptor from open(2) for FRM parsing so we can get errno.
49
  close(fd);
673.3.12 by Stewart Smith
fix RENAME TABLE
50
  return 0;
51
}
52
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
53
static int fill_table_proto(drizzled::message::Table *table_proto,
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
54
			    const char *table_name,
55
			    List<Create_field> &create_fields,
56
			    HA_CREATE_INFO *create_info,
57
			    uint32_t keys,
58
			    KEY *key_info)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
59
{
60
  Create_field *field_arg;
61
  List_iterator<Create_field> it(create_fields);
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
62
  drizzled::message::Table::StorageEngine *engine= table_proto->mutable_engine();
63
  drizzled::message::Table::TableOptions *table_options= table_proto->mutable_options();
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
64
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
65
  if (create_fields.elements > MAX_FIELDS)
66
  {
67
    my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
68
    return(1);
69
  }
70
971.1.14 by Monty Taylor
Slurp around strings rather than char* for storage engine name.
71
  engine->set_name(create_info->db_type->getName());
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
72
73
  table_proto->set_name(table_name);
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
74
  table_proto->set_type(drizzled::message::Table::STANDARD);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
75
76
  while ((field_arg= it++))
77
  {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
78
    drizzled::message::Table::Field *attribute;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
79
80
    attribute= table_proto->add_field();
81
    attribute->set_name(field_arg->field_name);
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
82
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
83
    attribute->set_pack_flag(field_arg->pack_flag); /* TODO: MUST DIE */
84
869.1.21 by Stewart Smith
correctly store nullable attribute in table proto. fix table_reader.
85
    if(f_maybe_null(field_arg->pack_flag))
86
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
87
      drizzled::message::Table::Field::FieldConstraints *constraints;
869.1.21 by Stewart Smith
correctly store nullable attribute in table proto. fix table_reader.
88
89
      constraints= attribute->mutable_constraints();
90
      constraints->set_is_nullable(true);
91
    }
92
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
93
    switch (field_arg->sql_type) {
94
    case DRIZZLE_TYPE_TINY:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
95
      attribute->set_type(drizzled::message::Table::Field::TINYINT);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
96
      break;
97
    case DRIZZLE_TYPE_LONG:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
98
      attribute->set_type(drizzled::message::Table::Field::INTEGER);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
99
      break;
100
    case DRIZZLE_TYPE_DOUBLE:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
101
      attribute->set_type(drizzled::message::Table::Field::DOUBLE);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
102
      break;
103
    case DRIZZLE_TYPE_NULL  :
104
      assert(1); /* Not a user definable type */
105
    case DRIZZLE_TYPE_TIMESTAMP:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
106
      attribute->set_type(drizzled::message::Table::Field::TIMESTAMP);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
107
      break;
108
    case DRIZZLE_TYPE_LONGLONG:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
109
      attribute->set_type(drizzled::message::Table::Field::BIGINT);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
110
      break;
111
    case DRIZZLE_TYPE_DATETIME:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
112
      attribute->set_type(drizzled::message::Table::Field::DATETIME);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
113
      break;
587 by Brian Aker
Merge stewert
114
    case DRIZZLE_TYPE_DATE:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
115
      attribute->set_type(drizzled::message::Table::Field::DATE);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
116
      break;
117
    case DRIZZLE_TYPE_VARCHAR:
118
      {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
119
        drizzled::message::Table::Field::StringFieldOptions *string_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
120
121
        string_field_options= attribute->mutable_string_options();
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
122
        attribute->set_type(drizzled::message::Table::Field::VARCHAR);
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
123
        string_field_options->set_length(field_arg->length
124
					 / field_arg->charset->mbmaxlen);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
125
        string_field_options->set_collation_id(field_arg->charset->number);
126
        string_field_options->set_collation(field_arg->charset->name);
127
128
        break;
129
      }
130
    case DRIZZLE_TYPE_NEWDECIMAL:
131
      {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
132
        drizzled::message::Table::Field::NumericFieldOptions *numeric_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
133
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
134
        attribute->set_type(drizzled::message::Table::Field::DECIMAL);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
135
        numeric_field_options= attribute->mutable_numeric_options();
136
        /* This is magic, I hate magic numbers -Brian */
137
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
138
        numeric_field_options->set_scale(field_arg->decimals);
139
        break;
140
      }
141
    case DRIZZLE_TYPE_ENUM:
142
      {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
143
        drizzled::message::Table::Field::SetFieldOptions *set_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
144
145
        assert(field_arg->interval);
146
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
147
        attribute->set_type(drizzled::message::Table::Field::ENUM);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
148
        set_field_options= attribute->mutable_set_options();
149
150
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
151
        {
152
          const char *src= field_arg->interval->type_names[pos];
153
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
154
          set_field_options->add_field_value(src);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
155
        }
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
156
        set_field_options->set_count_elements(set_field_options->field_value_size());
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
157
	set_field_options->set_collation_id(field_arg->charset->number);
158
        set_field_options->set_collation(field_arg->charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
159
        break;
160
      }
161
    case DRIZZLE_TYPE_BLOB:
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
162
      {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
163
	attribute->set_type(drizzled::message::Table::Field::BLOB);
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
164
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
165
        drizzled::message::Table::Field::StringFieldOptions *string_field_options;
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
166
167
        string_field_options= attribute->mutable_string_options();
168
        string_field_options->set_collation_id(field_arg->charset->number);
169
        string_field_options->set_collation(field_arg->charset->name);
170
      }
171
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
172
      break;
173
    default:
896.3.16 by jay.pipes at sun
Small fix to not abort() on a DEFAULT NULL, but instead return a new Item_null() from default_value()
174
      assert(0); /* Tell us, since this shouldn't happend */
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
175
    }
176
177
    if(field_arg->vcol_info)
178
    {
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
179
      uint32_t tmp_len;
180
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
181
					  field_arg->vcol_info->expr_str.str,
182
                                          field_arg->vcol_info->expr_str.str +
183
                                          field_arg->vcol_info->expr_str.length,
184
                                          VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
185
186
      if (tmp_len < field_arg->vcol_info->expr_str.length)
187
      {
188
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
189
                 field_arg->vcol_info->expr_str.str,"VIRTUAL COLUMN EXPRESSION",
190
                 (uint32_t) VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
191
        return(1);
192
      }
193
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
194
      drizzled::message::Table::Field::VirtualFieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
195
196
      field_options= attribute->mutable_virtual_options();
197
198
      field_options->set_type(attribute->type());
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
199
      attribute->set_type(drizzled::message::Table::Field::VIRTUAL);
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
200
896.3.8 by Stewart Smith
correctly store virtual column expression in proto
201
      string expr(field_arg->vcol_info->expr_str.str,
202
		  field_arg->vcol_info->expr_str.length);
203
204
      field_options->set_expression(expr);
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
205
      field_options->set_physically_stored(field_arg->is_stored);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
206
    }
207
208
#ifdef NOTDONE
209
    field_constraints= attribute->mutable_constraints();
210
    constraints->set_is_nullable(field_arg->def->null_value);
211
#endif
212
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
213
    switch(field_arg->column_format())
214
    {
215
    case COLUMN_FORMAT_TYPE_NOT_USED:
216
      break;
217
    case COLUMN_FORMAT_TYPE_DEFAULT:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
218
      attribute->set_format(drizzled::message::Table::Field::DefaultFormat);
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
219
      break;
220
    case COLUMN_FORMAT_TYPE_FIXED:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
221
      attribute->set_format(drizzled::message::Table::Field::FixedFormat);
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
222
      break;
223
    case COLUMN_FORMAT_TYPE_DYNAMIC:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
224
      attribute->set_format(drizzled::message::Table::Field::DynamicFormat);
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
225
      break;
226
    default:
896.3.16 by jay.pipes at sun
Small fix to not abort() on a DEFAULT NULL, but instead return a new Item_null() from default_value()
227
      assert(0); /* Tell us, since this shouldn't happend */
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
228
    }
229
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
230
    if (field_arg->comment.length)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
231
    {
232
      uint32_t tmp_len;
233
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
234
						  field_arg->comment.str,
235
						  field_arg->comment.str +
236
						  field_arg->comment.length,
237
						  COLUMN_COMMENT_MAXLEN);
238
239
      if (tmp_len < field_arg->comment.length)
240
      {
241
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
242
		 field_arg->comment.str,"COLUMN COMMENT",
243
		 (uint32_t) COLUMN_COMMENT_MAXLEN);
244
	return(1);
245
      }
246
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
247
      attribute->set_comment(field_arg->comment.str);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
248
    }
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
249
250
    if(field_arg->unireg_check == Field::NEXT_NUMBER)
251
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
252
      drizzled::message::Table::Field::NumericFieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
253
      field_options= attribute->mutable_numeric_options();
254
      field_options->set_is_autoincrement(true);
255
    }
256
257
    if(field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
258
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
259
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
260
      drizzled::message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
261
      field_options= attribute->mutable_options();
262
      field_options->set_default_value("NOW()");
263
    }
264
265
    if(field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
266
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
267
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
268
      drizzled::message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
269
      field_options= attribute->mutable_options();
270
      field_options->set_update_value("NOW()");
271
    }
272
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
273
    if(field_arg->def)
274
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
275
      drizzled::message::Table::Field::FieldOptions *field_options;
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
276
      field_options= attribute->mutable_options();
277
278
      if(field_arg->def->is_null())
279
      {
280
	field_options->set_default_null(true);
281
      }
282
      else
283
      {
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
284
	String d;
285
	String *default_value= field_arg->def->val_str(&d);
286
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
287
	assert(default_value);
288
289
	if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
290
	   || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
291
	   && ((field_arg->length / field_arg->charset->mbmaxlen)
292
	   < default_value->length()))
293
	{
294
	  my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
295
	  return 1;
296
	}
297
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
298
	if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
299
	    && field_arg->charset==&my_charset_bin)
300
	   || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
301
	    && field_arg->charset==&my_charset_bin))
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
302
	{
303
	  string bin_default;
304
	  bin_default.assign(default_value->c_ptr(),
305
			     default_value->length());
306
	  field_options->set_default_bin_value(bin_default);
307
	}
308
	else
309
	{
310
	  field_options->set_default_value(default_value->c_ptr());
311
	}
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
312
      }
313
    }
314
315
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
316
      drizzled::message::Table::Field::FieldOptions *field_options;
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
317
      field_options= attribute->mutable_options();
318
319
      field_options->set_length(field_arg->length);
320
    }
321
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
322
    assert(field_arg->unireg_check == Field::NONE
323
	   || field_arg->unireg_check == Field::NEXT_NUMBER
324
	   || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
325
	   || field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
326
	   || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD);
327
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
328
  }
329
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
330
  if (create_info->used_fields & HA_CREATE_USED_PACK_KEYS)
331
  {
332
    if(create_info->table_options & HA_OPTION_PACK_KEYS)
333
      table_options->set_pack_keys(true);
334
    else if(create_info->table_options & HA_OPTION_NO_PACK_KEYS)
335
      table_options->set_pack_keys(false);
336
  }
896.4.4 by Stewart Smith
for db_create_options: options HA_X can be set even if HA_USED_X isn't set in used.
337
  else
338
    if(create_info->table_options & HA_OPTION_PACK_KEYS)
339
      table_options->set_pack_keys(true);
340
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
341
342
  if (create_info->used_fields & HA_CREATE_USED_CHECKSUM)
343
  {
344
    assert(create_info->table_options & (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM));
345
346
    if(create_info->table_options & HA_OPTION_CHECKSUM)
347
      table_options->set_checksum(true);
348
    else
349
      table_options->set_checksum(false);
350
  }
896.4.4 by Stewart Smith
for db_create_options: options HA_X can be set even if HA_USED_X isn't set in used.
351
  else if(create_info->table_options & HA_OPTION_CHECKSUM)
352
    table_options->set_checksum(true);
353
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
354
355
  if (create_info->used_fields & HA_CREATE_USED_PAGE_CHECKSUM)
356
  {
357
    if (create_info->page_checksum == HA_CHOICE_YES)
358
      table_options->set_page_checksum(true);
359
    else if (create_info->page_checksum == HA_CHOICE_NO)
360
      table_options->set_page_checksum(false);
361
  }
896.4.4 by Stewart Smith
for db_create_options: options HA_X can be set even if HA_USED_X isn't set in used.
362
  else if (create_info->page_checksum == HA_CHOICE_YES)
363
    table_options->set_page_checksum(true);
364
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
365
366
  if (create_info->used_fields & HA_CREATE_USED_DELAY_KEY_WRITE)
367
  {
368
    if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
369
      table_options->set_delay_key_write(true);
370
    else if(create_info->table_options & HA_OPTION_NO_DELAY_KEY_WRITE)
371
      table_options->set_delay_key_write(false);
372
  }
896.4.4 by Stewart Smith
for db_create_options: options HA_X can be set even if HA_USED_X isn't set in used.
373
  else if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
374
    table_options->set_delay_key_write(true);
375
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
376
377
  switch(create_info->row_type)
378
  {
379
  case ROW_TYPE_DEFAULT:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
380
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DEFAULT);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
381
    break;
382
  case ROW_TYPE_FIXED:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
383
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_FIXED);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
384
    break;
385
  case ROW_TYPE_DYNAMIC:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
386
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DYNAMIC);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
387
    break;
388
  case ROW_TYPE_COMPRESSED:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
389
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPRESSED);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
390
    break;
391
  case ROW_TYPE_REDUNDANT:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
392
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_REDUNDANT);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
393
    break;
394
  case ROW_TYPE_COMPACT:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
395
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPACT);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
396
    break;
397
  case ROW_TYPE_PAGE:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
398
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_PAGE);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
399
    break;
400
  default:
401
    abort();
402
  }
403
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
404
  table_options->set_pack_record(create_info->table_options
405
				 & HA_OPTION_PACK_RECORD);
406
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
407
  if (create_info->comment.length)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
408
  {
409
    uint32_t tmp_len;
410
    tmp_len= system_charset_info->cset->charpos(system_charset_info,
411
						create_info->comment.str,
412
						create_info->comment.str +
413
						create_info->comment.length,
414
						TABLE_COMMENT_MAXLEN);
415
416
    if (tmp_len < create_info->comment.length)
417
    {
418
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
419
	       create_info->comment.str,"Table COMMENT",
420
	       (uint32_t) TABLE_COMMENT_MAXLEN);
421
      return(1);
422
    }
423
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
424
    table_options->set_comment(create_info->comment.str);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
425
  }
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
426
  if (create_info->default_table_charset)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
427
  {
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
428
    table_options->set_collation_id(
429
			       create_info->default_table_charset->number);
430
    table_options->set_collation(create_info->default_table_charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
431
  }
432
433
  if (create_info->connect_string.length)
434
    table_options->set_connect_string(create_info->connect_string.str);
435
436
  if (create_info->data_file_name)
437
    table_options->set_data_file_name(create_info->data_file_name);
438
439
  if (create_info->index_file_name)
440
    table_options->set_index_file_name(create_info->index_file_name);
441
442
  if (create_info->max_rows)
443
    table_options->set_max_rows(create_info->max_rows);
444
445
  if (create_info->min_rows)
446
    table_options->set_min_rows(create_info->min_rows);
447
448
  if (create_info->auto_increment_value)
449
    table_options->set_auto_increment_value(create_info->auto_increment_value);
450
451
  if (create_info->avg_row_length)
452
    table_options->set_avg_row_length(create_info->avg_row_length);
453
454
  if (create_info->key_block_size)
455
    table_options->set_key_block_size(create_info->key_block_size);
456
457
  if (create_info->block_size)
458
    table_options->set_block_size(create_info->block_size);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
459
460
  for (unsigned int i= 0; i < keys; i++)
461
  {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
462
    drizzled::message::Table::Index *idx;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
463
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
464
    idx= table_proto->add_indexes();
590.1.2 by Stewart Smith
store indexes in table definition protobuf
465
466
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
467
           (key_info[i].comment.length > 0));
468
469
    idx->set_name(key_info[i].name);
470
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
471
    idx->set_key_length(key_info[i].key_length);
472
590.1.2 by Stewart Smith
store indexes in table definition protobuf
473
    if(is_primary_key_name(key_info[i].name))
474
      idx->set_is_primary(true);
475
    else
476
      idx->set_is_primary(false);
477
478
    switch(key_info[i].algorithm)
479
    {
480
    case HA_KEY_ALG_HASH:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
481
      idx->set_type(drizzled::message::Table::Index::HASH);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
482
      break;
483
484
    case HA_KEY_ALG_BTREE:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
485
      idx->set_type(drizzled::message::Table::Index::BTREE);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
486
      break;
487
488
    case HA_KEY_ALG_RTREE:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
489
      idx->set_type(drizzled::message::Table::Index::RTREE);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
490
    case HA_KEY_ALG_FULLTEXT:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
491
      idx->set_type(drizzled::message::Table::Index::FULLTEXT);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
492
    case HA_KEY_ALG_UNDEF:
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
493
      idx->set_type(drizzled::message::Table::Index::UNKNOWN_INDEX);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
494
      break;
495
496
    default:
497
      abort(); /* Somebody's brain broke. haven't added index type to proto */
498
    }
499
500
    if (key_info[i].flags & HA_NOSAME)
501
      idx->set_is_unique(true);
502
    else
503
      idx->set_is_unique(false);
504
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
505
    drizzled::message::Table::Index::IndexOptions *index_options= idx->mutable_options();
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
506
507
    if(key_info[i].flags & HA_USES_BLOCK_SIZE)
508
      index_options->set_key_block_size(key_info[i].block_size);
509
510
    if(key_info[i].flags & HA_PACK_KEY)
511
      index_options->set_pack_key(true);
512
513
    if(key_info[i].flags & HA_BINARY_PACK_KEY)
514
      index_options->set_binary_pack_key(true);
515
516
    if(key_info[i].flags & HA_VAR_LENGTH_PART)
517
      index_options->set_var_length_key(true);
518
519
    if(key_info[i].flags & HA_NULL_PART_KEY)
520
      index_options->set_null_part_key(true);
521
522
    if(key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
523
      index_options->set_has_partial_segments(true);
524
525
    if(key_info[i].flags & HA_GENERATED_KEY)
526
      index_options->set_auto_generated_key(true);
527
528
    if (key_info[i].flags & HA_USES_COMMENT)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
529
    {
530
      uint32_t tmp_len;
531
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
532
						  key_info[i].comment.str,
533
						  key_info[i].comment.str +
534
						  key_info[i].comment.length,
535
						  TABLE_COMMENT_MAXLEN);
536
537
      if (tmp_len < key_info[i].comment.length)
538
      {
539
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
540
		 key_info[i].comment.str,"Index COMMENT",
541
		 (uint32_t) TABLE_COMMENT_MAXLEN);
542
	return(1);
543
      }
544
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
545
      idx->set_comment(key_info[i].comment.str);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
546
    }
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
547
    if(key_info[i].flags & ~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE | HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY | HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
548
      abort(); // Invalid (unknown) index flag.
590.1.2 by Stewart Smith
store indexes in table definition protobuf
549
550
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
551
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
552
      drizzled::message::Table::Index::IndexPart *idxpart;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
553
554
      idxpart= idx->add_index_part();
555
896.3.13 by Stewart Smith
compute key_part->offset instead of storing in proto.
556
      idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
557
558
      idxpart->set_compare_length(key_info[i].key_part[j].length);
896.3.1 by Stewart Smith
removal final 2 values in indexes from being read from FRM.
559
560
      idxpart->set_key_type(key_info[i].key_part[j].key_type);
561
590.1.2 by Stewart Smith
store indexes in table definition protobuf
562
    }
563
  }
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
564
565
  return 0;
566
}
567
568
int copy_table_proto_file(const char *from, const char* to)
569
{
570
  string dfesrc(from);
571
  string dfedst(to);
572
  string file_ext = ".dfe";
573
574
  dfesrc.append(file_ext);
575
  dfedst.append(file_ext);
576
577
  return my_copy(dfesrc.c_str(), dfedst.c_str(),
578
		 MYF(MY_DONT_OVERWRITE_FILE));
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
579
}
580
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
581
int rename_table_proto_file(const char *from, const char* to)
582
{
583
  string from_path(from);
584
  string to_path(to);
798.1.1 by Stewart Smith
critical performance fixes
585
  string file_ext = ".dfe";
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
586
587
  from_path.append(file_ext);
588
  to_path.append(file_ext);
589
590
  return my_rename(from_path.c_str(),to_path.c_str(),MYF(MY_WME));
591
}
592
813.5.3 by Stewart Smith
fix bug on failing to create table in rea_create_table.
593
int delete_table_proto_file(const char *file_name)
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
594
{
595
  string new_path(file_name);
798.1.1 by Stewart Smith
critical performance fixes
596
  string file_ext = ".dfe";
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
597
598
  new_path.append(file_ext);
599
  return my_delete(new_path.c_str(), MYF(0));
600
}
601
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
602
int table_proto_exists(const char *path)
603
{
604
  string proto_path(path);
605
  string file_ext(".dfe");
606
  proto_path.append(file_ext);
607
608
  int error= access(proto_path.c_str(), F_OK);
609
610
  if(error==0)
611
    return EEXIST;
612
  else
613
    return errno;
614
}
615
616
static int create_table_proto_file(const char *file_name,
617
				   const char *db,
618
				   const char *table_name,
619
				   HA_CREATE_INFO *create_info,
620
				   List<Create_field> &create_fields,
621
				   uint32_t keys,
622
				   KEY *key_info)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
623
{
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
624
  drizzled::message::Table table_proto;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
625
  string new_path(file_name);
798.1.1 by Stewart Smith
critical performance fixes
626
  string file_ext = ".dfe";
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
627
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
628
  if(fill_table_proto(&table_proto, table_name, create_fields, create_info,
629
		      keys, key_info))
630
    return -1;
631
632
  new_path.append(file_ext);
633
634
  int fd= open(new_path.c_str(), O_RDWR|O_CREAT|O_TRUNC, my_umask);
635
636
  if(fd==-1)
637
  {
638
    if(errno==ENOENT)
639
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
640
    else
641
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,errno);
642
    return errno;
643
  }
644
645
  google::protobuf::io::ZeroCopyOutputStream* output=
646
    new google::protobuf::io::FileOutputStream(fd);
647
648
  if (!table_proto.SerializeToZeroCopyStream(output))
649
  {
650
    delete output;
651
    close(fd);
652
    return errno;
653
  }
654
655
  delete output;
656
  close(fd);
657
  return 0;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
658
}
1 by brian
clean slate
659
660
/*
896.4.10 by Stewart Smith
some comment fixes in unireg.cc
661
  Create a table definition proto file and the tables
1 by brian
clean slate
662
663
  SYNOPSIS
664
    rea_create_table()
520.1.22 by Brian Aker
Second pass of thd cleanup
665
    session			Thread handler
1 by brian
clean slate
666
    path		Name of file (including database, without .frm)
667
    db			Data base name
668
    table_name		Table name
669
    create_info		create info parameters
670
    create_fields	Fields to create
671
    keys		number of keys to create
672
    key_info		Keys to create
673
    file		Handler to use
757 by Brian Aker
Fix for multple execution path for FRM creation.
674
    is_like             is true for mysql_create_like_schema_frm
1 by brian
clean slate
675
676
  RETURN
677
    0  ok
678
    1  error
679
*/
680
520.1.22 by Brian Aker
Second pass of thd cleanup
681
int rea_create_table(Session *session, const char *path,
1 by brian
clean slate
682
                     const char *db, const char *table_name,
683
                     HA_CREATE_INFO *create_info,
684
                     List<Create_field> &create_fields,
757 by Brian Aker
Fix for multple execution path for FRM creation.
685
                     uint32_t keys, KEY *key_info, handler *file,
686
                     bool is_like)
1 by brian
clean slate
687
{
757 by Brian Aker
Fix for multple execution path for FRM creation.
688
  /* Proto will blow up unless we give a name */
689
  assert(table_name);
690
691
  /* For is_like we return once the file has been created */
692
  if (is_like)
693
  {
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
694
    if (create_table_proto_file(path, db, table_name, create_info,
695
                                create_fields, keys, key_info)!=0)
757 by Brian Aker
Fix for multple execution path for FRM creation.
696
      return 1;
697
698
    return 0;
699
  }
700
  /* Here we need to build the full frm from the path */
701
  else
702
  {
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
703
    if (create_table_proto_file(path, db, table_name, create_info,
757 by Brian Aker
Fix for multple execution path for FRM creation.
704
                                create_fields, keys, key_info))
705
      return 1;
706
  }
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
707
1 by brian
clean slate
708
  // Make sure mysql_create_frm din't remove extension
520.1.22 by Brian Aker
Second pass of thd cleanup
709
  if (session->variables.keep_files_on_create)
1 by brian
clean slate
710
    create_info->options|= HA_CREATE_KEEP_FILES;
711
  if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
712
    goto err_handler;
757 by Brian Aker
Fix for multple execution path for FRM creation.
713
  if (ha_create_table(session, path, db, table_name,
714
                      create_info,0))
1 by brian
clean slate
715
    goto err_handler;
757 by Brian Aker
Fix for multple execution path for FRM creation.
716
  return 0;
1 by brian
clean slate
717
718
err_handler:
398.1.10 by Monty Taylor
Actually removed VOID() this time.
719
  file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info);
813.5.3 by Stewart Smith
fix bug on failing to create table in rea_create_table.
720
721
  delete_table_proto_file(path);
757 by Brian Aker
Fix for multple execution path for FRM creation.
722
723
  return 1;
1 by brian
clean slate
724
} /* rea_create_table */