~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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
16
#include "config.h"
549 by Monty Taylor
Took gettext.h out of header files.
17
#include <drizzled/error.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.
18
#include <drizzled/session.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
19
#include <drizzled/unireg.h>
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
20
#include "drizzled/sql_table.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
21
#include "drizzled/global_charset_info.h"
1273.10.2 by Stewart Smith
de-duplicate internal field type to field proto field type code. Consolidate that in replication_services and table_proto_write and now just have it in statement_transform.
22
#include "drizzled/message/statement_transform.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
23
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
24
#include "drizzled/internal/my_sys.h"
1241.9.62 by Monty Taylor
Removed plugin/myisam/myisam.h from session.h
25
1 by brian
clean slate
26
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
27
/* For proto */
28
#include <string>
29
#include <fstream>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
30
#include <fcntl.h>
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
31
#include <drizzled/message/schema.pb.h>
32
#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.
33
#include <google/protobuf/io/zero_copy_stream.h>
34
#include <google/protobuf/io/zero_copy_stream_impl.h>
1608.1.2 by Brian Aker
Merge enum test
35
#include <google/protobuf/message.h>
1095.3.1 by Stewart Smith
make writing the proto file sep to just creating the table. this allows the future removal of copy_table_proto_file. Add table_proto.h header for table proto manipulation stuff.
36
37
#include <drizzled/table_proto.h>
1638.8.1 by Stewart Smith
make the compare_length() of index parts of VARCHAR and BLOB (i.e. those with charsets) be a length in characters instead of bytes. This makes the logic converting a table proto back into a CREATE TABLE statement remotely sane. This does mean that if we increase the number of bytes utf8_general_ci uses, engines may have issues with their on disk formats (if they're not too smart)
38
#include <drizzled/charset.h>
1130.3.9 by Monty Taylor
Wrapped table_proto_write.cc code in namespace drizzled.
39
1668.7.1 by Stewart Smith
default values for DATE columns were being stored in the original string that the user entered in CREATE TABLE while what actually happens is that this string is typecast to DATE (e.g. if it had a time as well the time vanishes silently). This patch fixes what's stored in the table proto. This is visible when you use statement_transform for SHOW CREATE TABLE
40
#include "drizzled/function/time/typecast.h"
41
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
42
using namespace std;
1130.3.9 by Monty Taylor
Wrapped table_proto_write.cc code in namespace drizzled.
43
44
namespace drizzled {
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
45
1320.1.1 by Brian Aker
Light cleanup for references.
46
static int fill_table_proto(message::Table &table_proto,
47
                            List<CreateField> &create_fields,
48
                            HA_CREATE_INFO *create_info,
49
                            uint32_t keys,
1535 by Brian Aker
Rename of KEY to KeyInfo
50
                            KeyInfo *key_info)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
51
{
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
52
  CreateField *field_arg;
53
  List_iterator<CreateField> it(create_fields);
1320.1.1 by Brian Aker
Light cleanup for references.
54
  message::Table::TableOptions *table_options= table_proto.mutable_options();
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
55
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
56
  if (create_fields.elements > MAX_FIELDS)
57
  {
58
    my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
59
    return(1);
60
  }
61
1320.1.1 by Brian Aker
Light cleanup for references.
62
  assert(strcmp(table_proto.engine().name().c_str(),
1067.1.1 by Stewart Smith
Beginning of create table proto in parser: pass which Engine is being used for CREATE TABLE in table proto.
63
		create_info->db_type->getName().c_str())==0);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
64
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
65
  int field_number= 0;
1320.1.1 by Brian Aker
Light cleanup for references.
66
  bool use_existing_fields= table_proto.field_size() > 0;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
67
  while ((field_arg= it++))
68
  {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
69
    message::Table::Field *attribute;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
70
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
71
    /* some (one) code path for CREATE TABLE fills the proto
72
       out more than the others, so we already have partially
73
       filled out Field messages */
74
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
75
    if (use_existing_fields)
1320.1.1 by Brian Aker
Light cleanup for references.
76
      attribute= table_proto.mutable_field(field_number++);
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
77
    else
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
78
    {
79
      /* Other code paths still have to fill out the proto */
1320.1.1 by Brian Aker
Light cleanup for references.
80
      attribute= table_proto.add_field();
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
81
1372.1.3 by Brian Aker
Refactor for table message.
82
      if (field_arg->flags & NOT_NULL_FLAG)
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
83
      {
84
        message::Table::Field::FieldConstraints *constraints;
85
86
        constraints= attribute->mutable_constraints();
87
        constraints->set_is_nullable(false);
88
      }
1215.1.3 by stewart at flamingspork
[patch 03/17] set field name in parser, assert that its correct when filling out the rest of the table proto
89
90
      attribute->set_name(field_arg->field_name);
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
91
    }
92
93
    assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
1215.1.3 by stewart at flamingspork
[patch 03/17] set field name in parser, assert that its correct when filling out the rest of the table proto
94
    assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
95
1215.1.5 by stewart at flamingspork
[patch 05/17] Set Field type in proto in parser.
96
97
    message::Table::Field::FieldType parser_type= attribute->type();
98
1273.10.2 by Stewart Smith
de-duplicate internal field type to field proto field type code. Consolidate that in replication_services and table_proto_write and now just have it in statement_transform.
99
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
100
101
    switch (attribute->type()) {
102
    default: /* Only deal with types that need extra information */
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
103
      break;
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
104
    case message::Table::Field::DOUBLE:
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
105
      {
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
106
        /*
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
107
         * For DOUBLE, we only add a specific scale and precision iff
108
         * the fixed decimal point has been specified...
109
         */
110
        if (field_arg->decimals != NOT_FIXED_DEC)
111
        {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
112
          message::Table::Field::NumericFieldOptions *numeric_field_options;
1211.1.1 by Brian Aker
Updating with my change to to DECIMAL from NEWDECIMAL and Stewart's update
113
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
114
          numeric_field_options= attribute->mutable_numeric_options();
1211.1.1 by Brian Aker
Updating with my change to to DECIMAL from NEWDECIMAL and Stewart's update
115
116
          numeric_field_options->set_precision(field_arg->length);
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
117
          numeric_field_options->set_scale(field_arg->decimals);
118
        }
119
      }
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
120
      break;
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
121
    case message::Table::Field::VARCHAR:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
122
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
123
        message::Table::Field::StringFieldOptions *string_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
124
125
        string_field_options= attribute->mutable_string_options();
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
126
1215.1.14 by stewart at flamingspork
[patch 14/17] add length of CHAR column to proto in parser
127
        if (! use_existing_fields || string_field_options->length()==0)
128
          string_field_options->set_length(field_arg->length
129
                                           / field_arg->charset->mbmaxlen);
130
        else
131
          assert((uint32_t)string_field_options->length() == (uint32_t)(field_arg->length / field_arg->charset->mbmaxlen));
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
132
1215.1.17 by stewart at flamingspork
[patch 17/17] set varbinary charset in parser
133
        if (! string_field_options->has_collation())
134
        {
135
          string_field_options->set_collation_id(field_arg->charset->number);
136
          string_field_options->set_collation(field_arg->charset->name);
137
        }
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
138
        break;
139
      }
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
140
    case message::Table::Field::DECIMAL:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
141
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
142
        message::Table::Field::NumericFieldOptions *numeric_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
143
144
        numeric_field_options= attribute->mutable_numeric_options();
145
        /* This is magic, I hate magic numbers -Brian */
146
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
147
        numeric_field_options->set_scale(field_arg->decimals);
148
        break;
149
      }
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
150
    case message::Table::Field::ENUM:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
151
      {
1396 by Brian Aker
Simple rename.
152
        message::Table::Field::EnumerationValues *enumeration_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
153
154
        assert(field_arg->interval);
155
1396 by Brian Aker
Simple rename.
156
        enumeration_options= attribute->mutable_enumeration_values();
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
157
158
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
159
        {
160
          const char *src= field_arg->interval->type_names[pos];
161
1396 by Brian Aker
Simple rename.
162
          enumeration_options->add_field_value(src);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
163
        }
1396 by Brian Aker
Simple rename.
164
	enumeration_options->set_collation_id(field_arg->charset->number);
165
        enumeration_options->set_collation(field_arg->charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
166
        break;
167
      }
1273.2.17 by Stewart Smith
move conversion of enum_field_types to Field protobuf message type out into function so it can be reused in tmp table code.
168
    case message::Table::Field::BLOB:
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
169
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
170
        message::Table::Field::StringFieldOptions *string_field_options;
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
171
172
        string_field_options= attribute->mutable_string_options();
173
        string_field_options->set_collation_id(field_arg->charset->number);
174
        string_field_options->set_collation(field_arg->charset->name);
175
      }
176
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
177
      break;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
178
    }
179
1215.1.5 by stewart at flamingspork
[patch 05/17] Set Field type in proto in parser.
180
    assert (!use_existing_fields || parser_type == attribute->type());
181
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
182
#ifdef NOTDONE
183
    field_constraints= attribute->mutable_constraints();
184
    constraints->set_is_nullable(field_arg->def->null_value);
185
#endif
186
187
    if (field_arg->comment.length)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
188
    {
189
      uint32_t tmp_len;
190
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
191
						  field_arg->comment.str,
192
						  field_arg->comment.str +
193
						  field_arg->comment.length,
194
						  COLUMN_COMMENT_MAXLEN);
195
196
      if (tmp_len < field_arg->comment.length)
197
      {
198
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
199
		 field_arg->comment.str,"COLUMN COMMENT",
200
		 (uint32_t) COLUMN_COMMENT_MAXLEN);
201
	return(1);
202
      }
203
1215.1.4 by stewart at flamingspork
[patch 04/17] field comment set in table proto in parser
204
      if (! use_existing_fields)
205
        attribute->set_comment(field_arg->comment.str);
206
207
      assert(strcmp(attribute->comment().c_str(), field_arg->comment.str)==0);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
208
    }
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
209
1372.1.3 by Brian Aker
Refactor for table message.
210
    if (field_arg->unireg_check == Field::NEXT_NUMBER)
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
211
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
212
      message::Table::Field::NumericFieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
213
      field_options= attribute->mutable_numeric_options();
214
      field_options->set_is_autoincrement(true);
215
    }
216
1372.1.3 by Brian Aker
Refactor for table message.
217
    if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
218
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
219
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
220
      message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
221
      field_options= attribute->mutable_options();
1638.3.3 by Stewart Smith
store CURRENT_TIMESTAMP instead of NOW() in the table proto as this is what we end up displaying in SHOW CREATE so more accurately represents what's going on. Although it could go either way (it totally does not matter), this paves the way for SHOW CREATE TABLE running through statement_transform.
222
      field_options->set_default_expression("CURRENT_TIMESTAMP");
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
223
    }
224
1372.1.3 by Brian Aker
Refactor for table message.
225
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
226
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
227
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
228
      message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
229
      field_options= attribute->mutable_options();
1638.3.3 by Stewart Smith
store CURRENT_TIMESTAMP instead of NOW() in the table proto as this is what we end up displaying in SHOW CREATE so more accurately represents what's going on. Although it could go either way (it totally does not matter), this paves the way for SHOW CREATE TABLE running through statement_transform.
230
      field_options->set_update_expression("CURRENT_TIMESTAMP");
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
231
    }
232
1302.3.1 by Stewart Smith
correctly set FieldOptions default_null in table proto
233
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
234
    {
235
      message::Table::Field::FieldOptions *field_options;
236
      field_options= attribute->mutable_options();
237
238
      field_options->set_default_null(true);
239
    }
1372.1.3 by Brian Aker
Refactor for table message.
240
    if (field_arg->def)
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
241
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
242
      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.
243
      field_options= attribute->mutable_options();
1302.3.1 by Stewart Smith
correctly set FieldOptions default_null in table proto
244
 
1372.1.3 by Brian Aker
Refactor for table message.
245
      if (field_arg->def->is_null())
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
246
      {
247
	field_options->set_default_null(true);
248
      }
249
      else
250
      {
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
251
	String d;
252
	String *default_value= field_arg->def->val_str(&d);
253
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
254
	assert(default_value);
255
1372.1.3 by Brian Aker
Refactor for table message.
256
	if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
257
	   || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
258
	   && ((field_arg->length / field_arg->charset->mbmaxlen)
259
	   < default_value->length()))
260
	{
261
	  my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
262
	  return 1;
263
	}
264
1668.7.1 by Stewart Smith
default values for DATE columns were being stored in the original string that the user entered in CREATE TABLE while what actually happens is that this string is typecast to DATE (e.g. if it had a time as well the time vanishes silently). This patch fixes what's stored in the table proto. This is visible when you use statement_transform for SHOW CREATE TABLE
265
        if (field_arg->sql_type == DRIZZLE_TYPE_DATE
266
            || field_arg->sql_type == DRIZZLE_TYPE_DATETIME
267
            || field_arg->sql_type == DRIZZLE_TYPE_TIMESTAMP)
268
        {
269
          DRIZZLE_TIME ltime;
270
271
          if (field_arg->def->get_date(&ltime, TIME_FUZZY_DATE))
272
          {
273
            my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
274
                     default_value->c_str());
275
            return 1;
276
          }
277
278
          /* We now do the casting down to the appropriate type.
279
280
             Yes, this implicit casting is balls.
281
             It was previously done on reading the proto back in,
282
             but we really shouldn't store the bogus things in the proto,
283
             and instead do the casting behaviour here.
284
285
             the timestamp errors are taken care of elsewhere.
286
          */
287
288
          if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
289
          {
290
            Item *typecast= new Item_datetime_typecast(field_arg->def);
291
            typecast->quick_fix_field();
292
            typecast->val_str(default_value);
293
          }
294
          else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
295
          {
296
            Item *typecast= new Item_date_typecast(field_arg->def);
297
            typecast->quick_fix_field();
298
            typecast->val_str(default_value);
299
          }
300
        }
301
1372.1.3 by Brian Aker
Refactor for table message.
302
	if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
303
	    && field_arg->charset==&my_charset_bin)
304
	   || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
305
	    && 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.
306
	{
307
	  string bin_default;
308
	  bin_default.assign(default_value->c_ptr(),
309
			     default_value->length());
310
	  field_options->set_default_bin_value(bin_default);
311
	}
312
	else
313
	{
314
	  field_options->set_default_value(default_value->c_ptr());
315
	}
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
316
      }
317
    }
318
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
319
    assert(field_arg->unireg_check == Field::NONE
320
	   || field_arg->unireg_check == Field::NEXT_NUMBER
321
	   || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
322
	   || field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
323
	   || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD);
324
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
325
  }
326
1320.1.1 by Brian Aker
Light cleanup for references.
327
  assert(! use_existing_fields || (field_number == table_proto.field_size()));
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
328
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
329
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
330
    table_options->set_pack_record(true);
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
331
1668.3.1 by Stewart Smith
upper layer treats empty string for COMMENT as removing comment. Fix this in routine for filling out table protobuf message. (only user visible with statement_transform is used for SHOW CREATE TABLE
332
  if (table_options->has_comment() && table_options->comment().length() == 0)
333
    table_options->clear_comment();
334
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
335
  if (table_options->has_comment())
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
336
  {
337
    uint32_t tmp_len;
338
    tmp_len= system_charset_info->cset->charpos(system_charset_info,
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
339
                                                table_options->comment().c_str(),
340
                                                table_options->comment().c_str() +
341
                                                table_options->comment().length(),
342
                                                TABLE_COMMENT_MAXLEN);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
343
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
344
    if (tmp_len < table_options->comment().length())
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
345
    {
346
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
347
               table_options->comment().c_str(),"Table COMMENT",
348
               (uint32_t) TABLE_COMMENT_MAXLEN);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
349
      return(1);
350
    }
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
351
  }
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
352
1638.1.5 by Stewart Smith
explicit collation in table proto (from review)
353
  if (create_info->default_table_charset)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
354
  {
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
355
    table_options->set_collation_id(
356
			       create_info->default_table_charset->number);
357
    table_options->set_collation(create_info->default_table_charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
358
  }
359
1638.10.116 by Stewart Smith
only display AUTO_INCREMENT value if explicitly set by user (and preserve across ALTER TABLE).
360
  if (create_info->used_fields & HA_CREATE_USED_AUTO)
361
    table_options->set_has_user_set_auto_increment_value(true);
362
  else
363
    table_options->set_has_user_set_auto_increment_value(false);
364
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
365
  if (create_info->auto_increment_value)
366
    table_options->set_auto_increment_value(create_info->auto_increment_value);
367
1320.1.1 by Brian Aker
Light cleanup for references.
368
  for (uint32_t i= 0; i < keys; i++)
590.1.2 by Stewart Smith
store indexes in table definition protobuf
369
  {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
370
    message::Table::Index *idx;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
371
1320.1.1 by Brian Aker
Light cleanup for references.
372
    idx= table_proto.add_indexes();
590.1.2 by Stewart Smith
store indexes in table definition protobuf
373
374
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
375
           (key_info[i].comment.length > 0));
376
377
    idx->set_name(key_info[i].name);
378
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
379
    idx->set_key_length(key_info[i].key_length);
380
1372.1.3 by Brian Aker
Refactor for table message.
381
    if (is_primary_key_name(key_info[i].name))
590.1.2 by Stewart Smith
store indexes in table definition protobuf
382
      idx->set_is_primary(true);
383
    else
384
      idx->set_is_primary(false);
385
386
    switch(key_info[i].algorithm)
387
    {
388
    case HA_KEY_ALG_HASH:
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
389
      idx->set_type(message::Table::Index::HASH);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
390
      break;
391
392
    case HA_KEY_ALG_BTREE:
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
393
      idx->set_type(message::Table::Index::BTREE);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
394
      break;
395
396
    case HA_KEY_ALG_UNDEF:
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
397
      idx->set_type(message::Table::Index::UNKNOWN_INDEX);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
398
      break;
399
400
    default:
401
      abort(); /* Somebody's brain broke. haven't added index type to proto */
402
    }
403
404
    if (key_info[i].flags & HA_NOSAME)
405
      idx->set_is_unique(true);
406
    else
407
      idx->set_is_unique(false);
408
1537 by Brian Aker
Remove dead options/rename Option and remove the update that we no longer
409
    message::Table::Index::Options *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.
410
1372.1.3 by Brian Aker
Refactor for table message.
411
    if (key_info[i].flags & HA_USES_BLOCK_SIZE)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
412
      index_options->set_key_block_size(key_info[i].block_size);
413
1372.1.3 by Brian Aker
Refactor for table message.
414
    if (key_info[i].flags & HA_PACK_KEY)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
415
      index_options->set_pack_key(true);
416
1372.1.3 by Brian Aker
Refactor for table message.
417
    if (key_info[i].flags & HA_BINARY_PACK_KEY)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
418
      index_options->set_binary_pack_key(true);
419
1372.1.3 by Brian Aker
Refactor for table message.
420
    if (key_info[i].flags & HA_VAR_LENGTH_PART)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
421
      index_options->set_var_length_key(true);
422
1372.1.3 by Brian Aker
Refactor for table message.
423
    if (key_info[i].flags & HA_NULL_PART_KEY)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
424
      index_options->set_null_part_key(true);
425
1372.1.3 by Brian Aker
Refactor for table message.
426
    if (key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
427
      index_options->set_has_partial_segments(true);
428
1372.1.3 by Brian Aker
Refactor for table message.
429
    if (key_info[i].flags & HA_GENERATED_KEY)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
430
      index_options->set_auto_generated_key(true);
431
432
    if (key_info[i].flags & HA_USES_COMMENT)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
433
    {
434
      uint32_t tmp_len;
435
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
436
						  key_info[i].comment.str,
437
						  key_info[i].comment.str +
438
						  key_info[i].comment.length,
439
						  TABLE_COMMENT_MAXLEN);
440
441
      if (tmp_len < key_info[i].comment.length)
442
      {
443
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
444
		 key_info[i].comment.str,"Index COMMENT",
445
		 (uint32_t) TABLE_COMMENT_MAXLEN);
446
	return(1);
447
      }
448
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
449
      idx->set_comment(key_info[i].comment.str);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
450
    }
1816.2.6 by Monty Taylor
Fixed three more ICC warnings.
451
    static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
452
                                               HA_USES_BLOCK_SIZE | 
453
                                               HA_BINARY_PACK_KEY |
454
                                               HA_VAR_LENGTH_PART |
455
                                               HA_NULL_PART_KEY | 
456
                                               HA_KEY_HAS_PART_KEY_SEG |
457
                                               HA_GENERATED_KEY |
458
                                               HA_USES_COMMENT);
459
    if (key_info[i].flags & ~unknown_index_flag)
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
460
      abort(); // Invalid (unknown) index flag.
590.1.2 by Stewart Smith
store indexes in table definition protobuf
461
462
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
463
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
464
      message::Table::Index::IndexPart *idxpart;
1638.8.1 by Stewart Smith
make the compare_length() of index parts of VARCHAR and BLOB (i.e. those with charsets) be a length in characters instead of bytes. This makes the logic converting a table proto back into a CREATE TABLE statement remotely sane. This does mean that if we increase the number of bytes utf8_general_ci uses, engines may have issues with their on disk formats (if they're not too smart)
465
      const int fieldnr= key_info[i].key_part[j].fieldnr;
466
      int mbmaxlen= 1;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
467
468
      idxpart= idx->add_index_part();
469
1638.8.1 by Stewart Smith
make the compare_length() of index parts of VARCHAR and BLOB (i.e. those with charsets) be a length in characters instead of bytes. This makes the logic converting a table proto back into a CREATE TABLE statement remotely sane. This does mean that if we increase the number of bytes utf8_general_ci uses, engines may have issues with their on disk formats (if they're not too smart)
470
      idxpart->set_fieldnr(fieldnr);
471
472
      if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
473
          || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
474
      {
475
        uint32_t collation_id;
476
477
        if (table_proto.field(fieldnr).string_options().has_collation_id())
478
          collation_id= table_proto.field(fieldnr).string_options().collation_id();
479
        else
480
          collation_id= table_proto.options().collation_id();
481
482
        const CHARSET_INFO *cs= get_charset(collation_id);
483
484
        mbmaxlen= cs->mbmaxlen;
485
      }
486
487
      idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
488
    }
489
  }
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
490
1608.1.2 by Brian Aker
Merge enum test
491
  if (not table_proto.IsInitialized())
492
  {
493
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table_proto.InitializationErrorString().c_str());
494
    return 1;
495
  }
496
497
  /*
498
    Here we test to see if we can validate the Table Message before we continue. 
499
    We do this by serializing the protobuffer.
500
  */
501
  {
502
    string tmp_string;
503
504
    try {
505
      table_proto.SerializeToString(&tmp_string);
506
    }
507
508
    catch (...)
509
    {
510
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
511
               table_proto.InitializationErrorString().empty() ? "": table_proto.InitializationErrorString().c_str());
512
513
      return 1;
514
    }
515
  }
516
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
517
  return 0;
518
}
519
1 by brian
clean slate
520
/*
896.4.10 by Stewart Smith
some comment fixes in unireg.cc
521
  Create a table definition proto file and the tables
1 by brian
clean slate
522
523
  SYNOPSIS
524
    rea_create_table()
520.1.22 by Brian Aker
Second pass of thd cleanup
525
    session			Thread handler
1 by brian
clean slate
526
    path		Name of file (including database, without .frm)
527
    db			Data base name
528
    table_name		Table name
529
    create_info		create info parameters
530
    create_fields	Fields to create
531
    keys		number of keys to create
532
    key_info		Keys to create
533
534
  RETURN
535
    0  ok
536
    1  error
537
*/
538
1372.1.3 by Brian Aker
Refactor for table message.
539
bool rea_create_table(Session *session,
540
                      TableIdentifier &identifier,
541
                      message::Table &table_proto,
542
                      HA_CREATE_INFO *create_info,
543
                      List<CreateField> &create_fields,
1535 by Brian Aker
Rename of KEY to KeyInfo
544
                      uint32_t keys, KeyInfo *key_info)
1 by brian
clean slate
545
{
1685.2.13 by Brian Aker
Tiny cleanup in pass table_name where we no longer use it.
546
  assert(table_proto.has_name());
547
  if (fill_table_proto(table_proto, create_fields, create_info,
1382 by Brian Aker
We were printing out info on charset (which we don't need to do... and don't
548
                       keys, key_info))
1372.1.3 by Brian Aker
Refactor for table message.
549
    return false;
1095.3.18 by Stewart Smith
move writing the proto out from filling it so we can later override it with engines. Also refactor CREATE TABLE LIKE so that there's only one place where we write the proto (not one for normal and one from I_S).
550
1685.2.13 by Brian Aker
Tiny cleanup in pass table_name where we no longer use it.
551
  assert(table_proto.name() == identifier.getTableName());
552
1223.4.8 by Brian Aker
More table identifier love :)
553
  if (plugin::StorageEngine::createTable(*session,
1223.4.15 by Brian Aker
Final step to make createTable() use the TableIdentifier.
554
                                         identifier,
1537 by Brian Aker
Remove dead options/rename Option and remove the update that we no longer
555
                                         table_proto))
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
556
  {
1372.1.3 by Brian Aker
Refactor for table message.
557
    return false;
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
558
  }
559
1372.1.3 by Brian Aker
Refactor for table message.
560
  return true;
1 by brian
clean slate
561
562
} /* rea_create_table */
1130.3.9 by Monty Taylor
Wrapped table_proto_write.cc code in namespace drizzled.
563
564
} /* namespace drizzled */
1273.10.2 by Stewart Smith
de-duplicate internal field type to field proto field type code. Consolidate that in replication_services and table_proto_write and now just have it in statement_transform.
565