~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
1919.2.2 by Stewart Smith
throw an error on trying to create a table with a column of type NULL. Yes, the error message here isn't ideal...
99
    if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
100
    {
101
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
102
      return -1;
103
    }
104
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.
105
    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.
106
107
    switch (attribute->type()) {
108
    default: /* Only deal with types that need extra information */
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
109
      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.
110
    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.
111
      {
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.
112
        /*
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
113
         * For DOUBLE, we only add a specific scale and precision iff
114
         * the fixed decimal point has been specified...
115
         */
116
        if (field_arg->decimals != NOT_FIXED_DEC)
117
        {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
118
          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
119
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
120
          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
121
122
          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.
123
          numeric_field_options->set_scale(field_arg->decimals);
124
        }
125
      }
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
126
      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.
127
    case message::Table::Field::VARCHAR:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
128
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
129
        message::Table::Field::StringFieldOptions *string_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
130
131
        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.
132
1215.1.14 by stewart at flamingspork
[patch 14/17] add length of CHAR column to proto in parser
133
        if (! use_existing_fields || string_field_options->length()==0)
134
          string_field_options->set_length(field_arg->length
135
                                           / field_arg->charset->mbmaxlen);
136
        else
137
          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
138
1215.1.17 by stewart at flamingspork
[patch 17/17] set varbinary charset in parser
139
        if (! string_field_options->has_collation())
140
        {
141
          string_field_options->set_collation_id(field_arg->charset->number);
142
          string_field_options->set_collation(field_arg->charset->name);
143
        }
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
144
        break;
145
      }
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.
146
    case message::Table::Field::DECIMAL:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
147
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
148
        message::Table::Field::NumericFieldOptions *numeric_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
149
150
        numeric_field_options= attribute->mutable_numeric_options();
151
        /* This is magic, I hate magic numbers -Brian */
152
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
153
        numeric_field_options->set_scale(field_arg->decimals);
154
        break;
155
      }
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.
156
    case message::Table::Field::ENUM:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
157
      {
1396 by Brian Aker
Simple rename.
158
        message::Table::Field::EnumerationValues *enumeration_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
159
160
        assert(field_arg->interval);
161
1396 by Brian Aker
Simple rename.
162
        enumeration_options= attribute->mutable_enumeration_values();
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
163
164
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
165
        {
166
          const char *src= field_arg->interval->type_names[pos];
167
1396 by Brian Aker
Simple rename.
168
          enumeration_options->add_field_value(src);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
169
        }
1396 by Brian Aker
Simple rename.
170
	enumeration_options->set_collation_id(field_arg->charset->number);
171
        enumeration_options->set_collation(field_arg->charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
172
        break;
173
      }
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.
174
    case message::Table::Field::BLOB:
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
175
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
176
        message::Table::Field::StringFieldOptions *string_field_options;
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
177
178
        string_field_options= attribute->mutable_string_options();
179
        string_field_options->set_collation_id(field_arg->charset->number);
180
        string_field_options->set_collation(field_arg->charset->name);
181
      }
182
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
183
      break;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
184
    }
185
1215.1.5 by stewart at flamingspork
[patch 05/17] Set Field type in proto in parser.
186
    assert (!use_existing_fields || parser_type == attribute->type());
187
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
188
#ifdef NOTDONE
189
    field_constraints= attribute->mutable_constraints();
190
    constraints->set_is_nullable(field_arg->def->null_value);
191
#endif
192
193
    if (field_arg->comment.length)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
194
    {
195
      uint32_t tmp_len;
196
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
197
						  field_arg->comment.str,
198
						  field_arg->comment.str +
199
						  field_arg->comment.length,
200
						  COLUMN_COMMENT_MAXLEN);
201
202
      if (tmp_len < field_arg->comment.length)
203
      {
204
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
205
		 field_arg->comment.str,"COLUMN COMMENT",
206
		 (uint32_t) COLUMN_COMMENT_MAXLEN);
207
	return(1);
208
      }
209
1215.1.4 by stewart at flamingspork
[patch 04/17] field comment set in table proto in parser
210
      if (! use_existing_fields)
211
        attribute->set_comment(field_arg->comment.str);
212
213
      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.
214
    }
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
215
1372.1.3 by Brian Aker
Refactor for table message.
216
    if (field_arg->unireg_check == Field::NEXT_NUMBER)
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
217
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
218
      message::Table::Field::NumericFieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
219
      field_options= attribute->mutable_numeric_options();
220
      field_options->set_is_autoincrement(true);
221
    }
222
1372.1.3 by Brian Aker
Refactor for table message.
223
    if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
224
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
225
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
226
      message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
227
      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.
228
      field_options->set_default_expression("CURRENT_TIMESTAMP");
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
229
    }
230
1372.1.3 by Brian Aker
Refactor for table message.
231
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
232
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
233
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
234
      message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
235
      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.
236
      field_options->set_update_expression("CURRENT_TIMESTAMP");
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
237
    }
238
1302.3.1 by Stewart Smith
correctly set FieldOptions default_null in table proto
239
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
240
    {
241
      message::Table::Field::FieldOptions *field_options;
242
      field_options= attribute->mutable_options();
243
244
      field_options->set_default_null(true);
245
    }
1372.1.3 by Brian Aker
Refactor for table message.
246
    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.
247
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
248
      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.
249
      field_options= attribute->mutable_options();
1302.3.1 by Stewart Smith
correctly set FieldOptions default_null in table proto
250
 
1372.1.3 by Brian Aker
Refactor for table message.
251
      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.
252
      {
253
	field_options->set_default_null(true);
254
      }
255
      else
256
      {
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
257
	String d;
258
	String *default_value= field_arg->def->val_str(&d);
259
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
260
	assert(default_value);
261
1372.1.3 by Brian Aker
Refactor for table message.
262
	if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
263
	   || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
264
	   && ((field_arg->length / field_arg->charset->mbmaxlen)
265
	   < default_value->length()))
266
	{
267
	  my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
268
	  return 1;
269
	}
270
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
271
        if (field_arg->sql_type == DRIZZLE_TYPE_DATE
272
            || field_arg->sql_type == DRIZZLE_TYPE_DATETIME
273
            || field_arg->sql_type == DRIZZLE_TYPE_TIMESTAMP)
274
        {
275
          DRIZZLE_TIME ltime;
276
277
          if (field_arg->def->get_date(&ltime, TIME_FUZZY_DATE))
278
          {
279
            my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
280
                     default_value->c_str());
281
            return 1;
282
          }
283
284
          /* We now do the casting down to the appropriate type.
285
286
             Yes, this implicit casting is balls.
287
             It was previously done on reading the proto back in,
288
             but we really shouldn't store the bogus things in the proto,
289
             and instead do the casting behaviour here.
290
291
             the timestamp errors are taken care of elsewhere.
292
          */
293
294
          if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
295
          {
296
            Item *typecast= new Item_datetime_typecast(field_arg->def);
297
            typecast->quick_fix_field();
298
            typecast->val_str(default_value);
299
          }
300
          else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
301
          {
302
            Item *typecast= new Item_date_typecast(field_arg->def);
303
            typecast->quick_fix_field();
304
            typecast->val_str(default_value);
305
          }
306
        }
307
1372.1.3 by Brian Aker
Refactor for table message.
308
	if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
309
	    && field_arg->charset==&my_charset_bin)
310
	   || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
311
	    && 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.
312
	{
313
	  string bin_default;
314
	  bin_default.assign(default_value->c_ptr(),
315
			     default_value->length());
316
	  field_options->set_default_bin_value(bin_default);
317
	}
318
	else
319
	{
320
	  field_options->set_default_value(default_value->c_ptr());
321
	}
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
322
      }
323
    }
324
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
325
    assert(field_arg->unireg_check == Field::NONE
326
	   || field_arg->unireg_check == Field::NEXT_NUMBER
327
	   || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
328
	   || field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
329
	   || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD);
330
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
331
  }
332
1320.1.1 by Brian Aker
Light cleanup for references.
333
  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
334
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
335
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
336
    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.
337
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
338
  if (table_options->has_comment() && table_options->comment().length() == 0)
339
    table_options->clear_comment();
340
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
341
  if (table_options->has_comment())
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
342
  {
343
    uint32_t tmp_len;
344
    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).
345
                                                table_options->comment().c_str(),
346
                                                table_options->comment().c_str() +
347
                                                table_options->comment().length(),
348
                                                TABLE_COMMENT_MAXLEN);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
349
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
350
    if (tmp_len < table_options->comment().length())
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
351
    {
352
      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).
353
               table_options->comment().c_str(),"Table COMMENT",
354
               (uint32_t) TABLE_COMMENT_MAXLEN);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
355
      return(1);
356
    }
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
357
  }
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
358
1638.1.5 by Stewart Smith
explicit collation in table proto (from review)
359
  if (create_info->default_table_charset)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
360
  {
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
361
    table_options->set_collation_id(
362
			       create_info->default_table_charset->number);
363
    table_options->set_collation(create_info->default_table_charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
364
  }
365
1638.10.116 by Stewart Smith
only display AUTO_INCREMENT value if explicitly set by user (and preserve across ALTER TABLE).
366
  if (create_info->used_fields & HA_CREATE_USED_AUTO)
367
    table_options->set_has_user_set_auto_increment_value(true);
368
  else
369
    table_options->set_has_user_set_auto_increment_value(false);
370
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
371
  if (create_info->auto_increment_value)
372
    table_options->set_auto_increment_value(create_info->auto_increment_value);
373
1320.1.1 by Brian Aker
Light cleanup for references.
374
  for (uint32_t i= 0; i < keys; i++)
590.1.2 by Stewart Smith
store indexes in table definition protobuf
375
  {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
376
    message::Table::Index *idx;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
377
1320.1.1 by Brian Aker
Light cleanup for references.
378
    idx= table_proto.add_indexes();
590.1.2 by Stewart Smith
store indexes in table definition protobuf
379
380
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
381
           (key_info[i].comment.length > 0));
382
383
    idx->set_name(key_info[i].name);
384
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
385
    idx->set_key_length(key_info[i].key_length);
386
1372.1.3 by Brian Aker
Refactor for table message.
387
    if (is_primary_key_name(key_info[i].name))
590.1.2 by Stewart Smith
store indexes in table definition protobuf
388
      idx->set_is_primary(true);
389
    else
390
      idx->set_is_primary(false);
391
392
    switch(key_info[i].algorithm)
393
    {
394
    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'
395
      idx->set_type(message::Table::Index::HASH);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
396
      break;
397
398
    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'
399
      idx->set_type(message::Table::Index::BTREE);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
400
      break;
401
402
    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'
403
      idx->set_type(message::Table::Index::UNKNOWN_INDEX);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
404
      break;
405
406
    default:
407
      abort(); /* Somebody's brain broke. haven't added index type to proto */
408
    }
409
410
    if (key_info[i].flags & HA_NOSAME)
411
      idx->set_is_unique(true);
412
    else
413
      idx->set_is_unique(false);
414
1537 by Brian Aker
Remove dead options/rename Option and remove the update that we no longer
415
    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.
416
1372.1.3 by Brian Aker
Refactor for table message.
417
    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.
418
      index_options->set_key_block_size(key_info[i].block_size);
419
1372.1.3 by Brian Aker
Refactor for table message.
420
    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.
421
      index_options->set_pack_key(true);
422
1372.1.3 by Brian Aker
Refactor for table message.
423
    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.
424
      index_options->set_binary_pack_key(true);
425
1372.1.3 by Brian Aker
Refactor for table message.
426
    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.
427
      index_options->set_var_length_key(true);
428
1372.1.3 by Brian Aker
Refactor for table message.
429
    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.
430
      index_options->set_null_part_key(true);
431
1372.1.3 by Brian Aker
Refactor for table message.
432
    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.
433
      index_options->set_has_partial_segments(true);
434
1372.1.3 by Brian Aker
Refactor for table message.
435
    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.
436
      index_options->set_auto_generated_key(true);
437
438
    if (key_info[i].flags & HA_USES_COMMENT)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
439
    {
440
      uint32_t tmp_len;
441
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
442
						  key_info[i].comment.str,
443
						  key_info[i].comment.str +
444
						  key_info[i].comment.length,
445
						  TABLE_COMMENT_MAXLEN);
446
447
      if (tmp_len < key_info[i].comment.length)
448
      {
449
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
450
		 key_info[i].comment.str,"Index COMMENT",
451
		 (uint32_t) TABLE_COMMENT_MAXLEN);
452
	return(1);
453
      }
454
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
455
      idx->set_comment(key_info[i].comment.str);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
456
    }
1816.2.6 by Monty Taylor
Fixed three more ICC warnings.
457
    static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
458
                                               HA_USES_BLOCK_SIZE | 
459
                                               HA_BINARY_PACK_KEY |
460
                                               HA_VAR_LENGTH_PART |
461
                                               HA_NULL_PART_KEY | 
462
                                               HA_KEY_HAS_PART_KEY_SEG |
463
                                               HA_GENERATED_KEY |
464
                                               HA_USES_COMMENT);
465
    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.
466
      abort(); // Invalid (unknown) index flag.
590.1.2 by Stewart Smith
store indexes in table definition protobuf
467
468
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
469
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
470
      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)
471
      const int fieldnr= key_info[i].key_part[j].fieldnr;
472
      int mbmaxlen= 1;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
473
474
      idxpart= idx->add_index_part();
475
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)
476
      idxpart->set_fieldnr(fieldnr);
477
478
      if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
479
          || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
480
      {
481
        uint32_t collation_id;
482
483
        if (table_proto.field(fieldnr).string_options().has_collation_id())
484
          collation_id= table_proto.field(fieldnr).string_options().collation_id();
485
        else
486
          collation_id= table_proto.options().collation_id();
487
488
        const CHARSET_INFO *cs= get_charset(collation_id);
489
490
        mbmaxlen= cs->mbmaxlen;
491
      }
492
493
      idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
494
    }
495
  }
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
496
1608.1.2 by Brian Aker
Merge enum test
497
  if (not table_proto.IsInitialized())
498
  {
499
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table_proto.InitializationErrorString().c_str());
500
    return 1;
501
  }
502
503
  /*
504
    Here we test to see if we can validate the Table Message before we continue. 
505
    We do this by serializing the protobuffer.
506
  */
507
  {
508
    string tmp_string;
509
510
    try {
511
      table_proto.SerializeToString(&tmp_string);
512
    }
513
514
    catch (...)
515
    {
516
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
517
               table_proto.InitializationErrorString().empty() ? "": table_proto.InitializationErrorString().c_str());
518
519
      return 1;
520
    }
521
  }
522
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
523
  return 0;
524
}
525
1 by brian
clean slate
526
/*
896.4.10 by Stewart Smith
some comment fixes in unireg.cc
527
  Create a table definition proto file and the tables
1 by brian
clean slate
528
529
  SYNOPSIS
530
    rea_create_table()
520.1.22 by Brian Aker
Second pass of thd cleanup
531
    session			Thread handler
1 by brian
clean slate
532
    path		Name of file (including database, without .frm)
533
    db			Data base name
534
    table_name		Table name
535
    create_info		create info parameters
536
    create_fields	Fields to create
537
    keys		number of keys to create
538
    key_info		Keys to create
539
540
  RETURN
541
    0  ok
542
    1  error
543
*/
544
1372.1.3 by Brian Aker
Refactor for table message.
545
bool rea_create_table(Session *session,
1954.2.3 by Brian Aker
Update tableidentifier so that it is const in many callers.
546
                      const TableIdentifier &identifier,
1372.1.3 by Brian Aker
Refactor for table message.
547
                      message::Table &table_proto,
548
                      HA_CREATE_INFO *create_info,
549
                      List<CreateField> &create_fields,
1535 by Brian Aker
Rename of KEY to KeyInfo
550
                      uint32_t keys, KeyInfo *key_info)
1 by brian
clean slate
551
{
1685.2.13 by Brian Aker
Tiny cleanup in pass table_name where we no longer use it.
552
  assert(table_proto.has_name());
553
  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
554
                       keys, key_info))
1372.1.3 by Brian Aker
Refactor for table message.
555
    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).
556
1685.2.13 by Brian Aker
Tiny cleanup in pass table_name where we no longer use it.
557
  assert(table_proto.name() == identifier.getTableName());
558
1223.4.8 by Brian Aker
More table identifier love :)
559
  if (plugin::StorageEngine::createTable(*session,
1223.4.15 by Brian Aker
Final step to make createTable() use the TableIdentifier.
560
                                         identifier,
1537 by Brian Aker
Remove dead options/rename Option and remove the update that we no longer
561
                                         table_proto))
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
562
  {
1372.1.3 by Brian Aker
Refactor for table message.
563
    return false;
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
564
  }
565
1372.1.3 by Brian Aker
Refactor for table message.
566
  return true;
1 by brian
clean slate
567
568
} /* rea_create_table */
1130.3.9 by Monty Taylor
Wrapped table_proto_write.cc code in namespace drizzled.
569
570
} /* 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.
571