~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
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
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>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
20
#include <drizzled/sql_table.h>
21
#include <drizzled/global_charset_info.h>
22
#include <drizzled/message/statement_transform.h>
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
23
2148.7.12 by Brian Aker
Merge in header fixes.
24
#include <drizzled/plugin/storage_engine.h>
25
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
26
#include <drizzled/internal/my_sys.h>
27
#include <drizzled/typelib.h>
1 by brian
clean slate
28
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
29
/* For proto */
30
#include <string>
31
#include <fstream>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
32
#include <fcntl.h>
2187.7.6 by Brian Aker
This fixes the message such that the table inherits the no replication
33
#include <drizzled/message/schema.h>
34
#include <drizzled/message/table.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.
35
#include <google/protobuf/io/zero_copy_stream.h>
36
#include <google/protobuf/io/zero_copy_stream_impl.h>
1608.1.2 by Brian Aker
Merge enum test
37
#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.
38
39
#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)
40
#include <drizzled/charset.h>
1130.3.9 by Monty Taylor
Wrapped table_proto_write.cc code in namespace drizzled.
41
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
42
#include <drizzled/function/time/typecast.h>
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
43
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
44
using namespace std;
1130.3.9 by Monty Taylor
Wrapped table_proto_write.cc code in namespace drizzled.
45
46
namespace drizzled {
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
47
2187.7.6 by Brian Aker
This fixes the message such that the table inherits the no replication
48
bool fill_table_proto(identifier::Table::const_reference identifier,
49
                      message::Table &table_proto,
2064.2.2 by Brian Aker
Formattting, etc.
50
                      List<CreateField> &create_fields,
51
                      HA_CREATE_INFO *create_info,
52
                      uint32_t keys,
53
                      KeyInfo *key_info)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
54
{
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
55
  CreateField *field_arg;
2183.2.10 by Olaf van der Spek
Use List::begin()
56
  List<CreateField>::iterator it(create_fields.begin());
1320.1.1 by Brian Aker
Light cleanup for references.
57
  message::Table::TableOptions *table_options= table_proto.mutable_options();
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
58
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
59
  if (create_fields.elements > MAX_FIELDS)
60
  {
61
    my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
2064.2.2 by Brian Aker
Formattting, etc.
62
    return true;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
63
  }
64
1320.1.1 by Brian Aker
Light cleanup for references.
65
  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.
66
		create_info->db_type->getName().c_str())==0);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
67
2187.7.6 by Brian Aker
This fixes the message such that the table inherits the no replication
68
  message::schema::shared_ptr schema_message= plugin::StorageEngine::getSchemaDefinition(identifier);
69
70
  if (schema_message and not message::is_replicated(*schema_message))
71
  {
72
    message::set_is_replicated(table_proto, false);
73
  }
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
  int field_number= 0;
1320.1.1 by Brian Aker
Light cleanup for references.
76
  bool use_existing_fields= table_proto.field_size() > 0;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
77
  while ((field_arg= it++))
78
  {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
79
    message::Table::Field *attribute;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
80
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.
81
    /* some (one) code path for CREATE TABLE fills the proto
82
       out more than the others, so we already have partially
83
       filled out Field messages */
84
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
85
    if (use_existing_fields)
2008.2.3 by Brian Aker
Fixing up a, somewhat, hidden unsigned type to solve a few issues around
86
    {
1320.1.1 by Brian Aker
Light cleanup for references.
87
      attribute= table_proto.mutable_field(field_number++);
2008.2.3 by Brian Aker
Fixing up a, somewhat, hidden unsigned type to solve a few issues around
88
    }
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
89
    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.
90
    {
91
      /* Other code paths still have to fill out the proto */
1320.1.1 by Brian Aker
Light cleanup for references.
92
      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
93
1372.1.3 by Brian Aker
Refactor for table message.
94
      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.
95
      {
2064.2.1 by Brian Aker
Fixes naming conventions and issues around notnull being "true" by default.
96
        attribute->mutable_constraints()->set_is_notnull(true);
2008.2.4 by Brian Aker
Merge in additional fixes for sign, plus alter table, plus TIME on
97
      }
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.
98
2008.2.4 by Brian Aker
Merge in additional fixes for sign, plus alter table, plus TIME on
99
      if (field_arg->flags & UNSIGNED_FLAG and 
100
          (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
101
      {
102
        field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
103
        attribute->mutable_constraints()->set_is_unsigned(true);
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.
104
      }
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
105
106
      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.
107
    }
108
2064.2.1 by Brian Aker
Fixes naming conventions and issues around notnull being "true" by default.
109
    assert(((field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_notnull());
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
110
    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
111
1215.1.5 by stewart at flamingspork
[patch 05/17] Set Field type in proto in parser.
112
113
    message::Table::Field::FieldType parser_type= attribute->type();
114
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...
115
    if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
116
    {
117
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
2064.2.2 by Brian Aker
Formattting, etc.
118
      return true;
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...
119
    }
120
2008.2.3 by Brian Aker
Fixing up a, somewhat, hidden unsigned type to solve a few issues around
121
    if (field_arg->flags & UNSIGNED_FLAG and 
122
       (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
123
    {
124
      message::Table::Field::FieldConstraints *constraints= attribute->mutable_constraints();
125
126
      field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
127
      constraints->set_is_unsigned(true);
128
    }
129
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.
130
    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.
131
132
    switch (attribute->type()) {
2057.2.8 by Brian Aker
Remove default from switch for field types.
133
    case message::Table::Field::BIGINT:
134
    case message::Table::Field::INTEGER:
135
    case message::Table::Field::DATE:
136
    case message::Table::Field::DATETIME:
137
    case message::Table::Field::UUID:
138
    case message::Table::Field::TIME:
139
    case message::Table::Field::BOOLEAN:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
140
      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.
141
    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.
142
      {
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.
143
        /*
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
144
         * For DOUBLE, we only add a specific scale and precision iff
145
         * the fixed decimal point has been specified...
146
         */
147
        if (field_arg->decimals != NOT_FIXED_DEC)
148
        {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
149
          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
150
1119.9.8 by Jay Pipes
Fixes incorrect non-setup of optional scale and precision arguments for DOUBLE in proto.
151
          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
152
153
          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.
154
          numeric_field_options->set_scale(field_arg->decimals);
155
        }
156
      }
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
157
      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.
158
    case message::Table::Field::VARCHAR:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
159
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
160
        message::Table::Field::StringFieldOptions *string_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
161
162
        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.
163
1215.1.14 by stewart at flamingspork
[patch 14/17] add length of CHAR column to proto in parser
164
        if (! use_existing_fields || string_field_options->length()==0)
165
          string_field_options->set_length(field_arg->length
166
                                           / field_arg->charset->mbmaxlen);
167
        else
168
          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
169
1215.1.17 by stewart at flamingspork
[patch 17/17] set varbinary charset in parser
170
        if (! string_field_options->has_collation())
171
        {
172
          string_field_options->set_collation_id(field_arg->charset->number);
173
          string_field_options->set_collation(field_arg->charset->name);
174
        }
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
175
        break;
176
      }
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.
177
    case message::Table::Field::DECIMAL:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
178
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
179
        message::Table::Field::NumericFieldOptions *numeric_field_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
180
181
        numeric_field_options= attribute->mutable_numeric_options();
182
        /* This is magic, I hate magic numbers -Brian */
183
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
184
        numeric_field_options->set_scale(field_arg->decimals);
185
        break;
186
      }
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.
187
    case message::Table::Field::ENUM:
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
188
      {
1396 by Brian Aker
Simple rename.
189
        message::Table::Field::EnumerationValues *enumeration_options;
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
190
191
        assert(field_arg->interval);
192
1396 by Brian Aker
Simple rename.
193
        enumeration_options= attribute->mutable_enumeration_values();
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
194
195
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
196
        {
197
          const char *src= field_arg->interval->type_names[pos];
198
1396 by Brian Aker
Simple rename.
199
          enumeration_options->add_field_value(src);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
200
        }
1396 by Brian Aker
Simple rename.
201
	enumeration_options->set_collation_id(field_arg->charset->number);
202
        enumeration_options->set_collation(field_arg->charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
203
        break;
204
      }
2057.2.7 by Brian Aker
Remove need for committed type for microtime in proto.
205
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.
206
    case message::Table::Field::BLOB:
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
207
      {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
208
        message::Table::Field::StringFieldOptions *string_field_options;
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
209
210
        string_field_options= attribute->mutable_string_options();
211
        string_field_options->set_collation_id(field_arg->charset->number);
212
        string_field_options->set_collation(field_arg->charset->name);
213
      }
214
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
215
      break;
2057.2.7 by Brian Aker
Remove need for committed type for microtime in proto.
216
217
    case message::Table::Field::EPOCH:
218
      {
219
        if (field_arg->sql_type == DRIZZLE_TYPE_MICROTIME)
220
          attribute->mutable_time_options()->set_microseconds(true);
221
      }
222
223
      break;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
224
    }
225
1215.1.5 by stewart at flamingspork
[patch 05/17] Set Field type in proto in parser.
226
    assert (!use_existing_fields || parser_type == attribute->type());
227
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
228
#ifdef NOTDONE
229
    field_constraints= attribute->mutable_constraints();
230
    constraints->set_is_nullable(field_arg->def->null_value);
231
#endif
232
233
    if (field_arg->comment.length)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
234
    {
235
      uint32_t tmp_len;
236
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
237
						  field_arg->comment.str,
238
						  field_arg->comment.str +
239
						  field_arg->comment.length,
240
						  COLUMN_COMMENT_MAXLEN);
241
242
      if (tmp_len < field_arg->comment.length)
243
      {
244
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
245
		 field_arg->comment.str,"COLUMN COMMENT",
246
		 (uint32_t) COLUMN_COMMENT_MAXLEN);
2064.2.2 by Brian Aker
Formattting, etc.
247
	return true;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
248
      }
249
1215.1.4 by stewart at flamingspork
[patch 04/17] field comment set in table proto in parser
250
      if (! use_existing_fields)
251
        attribute->set_comment(field_arg->comment.str);
252
253
      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.
254
    }
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
255
1372.1.3 by Brian Aker
Refactor for table message.
256
    if (field_arg->unireg_check == Field::NEXT_NUMBER)
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
257
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
258
      message::Table::Field::NumericFieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
259
      field_options= attribute->mutable_numeric_options();
260
      field_options->set_is_autoincrement(true);
261
    }
262
1372.1.3 by Brian Aker
Refactor for table message.
263
    if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
264
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
265
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
266
      message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
267
      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.
268
      field_options->set_default_expression("CURRENT_TIMESTAMP");
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
269
    }
270
1372.1.3 by Brian Aker
Refactor for table message.
271
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
272
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
273
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
274
      message::Table::Field::FieldOptions *field_options;
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
275
      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.
276
      field_options->set_update_expression("CURRENT_TIMESTAMP");
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
277
    }
278
2064.2.1 by Brian Aker
Fixes naming conventions and issues around notnull being "true" by default.
279
    if (field_arg->def == NULL  && not attribute->constraints().is_notnull())
1302.3.1 by Stewart Smith
correctly set FieldOptions default_null in table proto
280
    {
281
      message::Table::Field::FieldOptions *field_options;
282
      field_options= attribute->mutable_options();
283
284
      field_options->set_default_null(true);
285
    }
1372.1.3 by Brian Aker
Refactor for table message.
286
    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.
287
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
288
      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.
289
      field_options= attribute->mutable_options();
1302.3.1 by Stewart Smith
correctly set FieldOptions default_null in table proto
290
 
1372.1.3 by Brian Aker
Refactor for table message.
291
      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.
292
      {
293
	field_options->set_default_null(true);
294
      }
295
      else
296
      {
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
297
	String d;
298
	String *default_value= field_arg->def->val_str(&d);
299
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
300
	assert(default_value);
301
1372.1.3 by Brian Aker
Refactor for table message.
302
	if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
303
	   || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
304
	   && ((field_arg->length / field_arg->charset->mbmaxlen)
305
	   < default_value->length()))
306
	{
307
	  my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
2064.2.2 by Brian Aker
Formattting, etc.
308
	  return true;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
309
	}
310
2167.3.2 by Brian Aker
Make use of isDateTime
311
        if (field::isDateTime(field_arg->sql_type))
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
312
        {
2030.1.5 by Brian Aker
Update for moving DRIZZLE_TIME to type::Time
313
          type::Time ltime;
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
314
2104.2.8 by Brian Aker
Merge in reference from pointer.
315
          if (field_arg->def->get_date(ltime, TIME_FUZZY_DATE))
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
316
          {
317
            my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
318
                     default_value->c_str());
2064.2.2 by Brian Aker
Formattting, etc.
319
            return true;
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
320
          }
321
322
          /* We now do the casting down to the appropriate type.
323
324
             Yes, this implicit casting is balls.
325
             It was previously done on reading the proto back in,
326
             but we really shouldn't store the bogus things in the proto,
327
             and instead do the casting behaviour here.
328
329
             the timestamp errors are taken care of elsewhere.
330
          */
331
332
          if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
333
          {
334
            Item *typecast= new Item_datetime_typecast(field_arg->def);
335
            typecast->quick_fix_field();
336
            typecast->val_str(default_value);
337
          }
338
          else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
339
          {
340
            Item *typecast= new Item_date_typecast(field_arg->def);
341
            typecast->quick_fix_field();
342
            typecast->val_str(default_value);
343
          }
344
        }
345
1372.1.3 by Brian Aker
Refactor for table message.
346
	if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
347
	    && field_arg->charset==&my_charset_bin)
348
	   || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
349
	    && 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.
350
	{
351
	  string bin_default;
352
	  bin_default.assign(default_value->c_ptr(),
353
			     default_value->length());
354
	  field_options->set_default_bin_value(bin_default);
355
	}
356
	else
357
	{
358
	  field_options->set_default_value(default_value->c_ptr());
359
	}
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
360
      }
361
    }
362
869.1.10 by Stewart Smith
Add some missing things to field storage in proto
363
    assert(field_arg->unireg_check == Field::NONE
364
	   || field_arg->unireg_check == Field::NEXT_NUMBER
365
	   || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
366
	   || field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
367
	   || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD);
368
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
369
  }
370
1320.1.1 by Brian Aker
Light cleanup for references.
371
  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
372
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
373
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
374
    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.
375
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
376
  if (table_options->has_comment() && table_options->comment().length() == 0)
377
    table_options->clear_comment();
378
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
379
  if (table_options->has_comment())
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
380
  {
381
    uint32_t tmp_len;
382
    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).
383
                                                table_options->comment().c_str(),
384
                                                table_options->comment().c_str() +
385
                                                table_options->comment().length(),
386
                                                TABLE_COMMENT_MAXLEN);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
387
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
388
    if (tmp_len < table_options->comment().length())
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
389
    {
390
      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).
391
               table_options->comment().c_str(),"Table COMMENT",
392
               (uint32_t) TABLE_COMMENT_MAXLEN);
2064.2.2 by Brian Aker
Formattting, etc.
393
      return true;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
394
    }
1116.1.1 by Brian Aker
Fix for Stewart's patch (includes hack to solve MAX rows problem).
395
  }
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
396
1638.1.5 by Stewart Smith
explicit collation in table proto (from review)
397
  if (create_info->default_table_charset)
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
398
  {
2057.2.8 by Brian Aker
Remove default from switch for field types.
399
    table_options->set_collation_id(create_info->default_table_charset->number);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
400
    table_options->set_collation(create_info->default_table_charset->name);
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
401
  }
402
1638.10.116 by Stewart Smith
only display AUTO_INCREMENT value if explicitly set by user (and preserve across ALTER TABLE).
403
  if (create_info->used_fields & HA_CREATE_USED_AUTO)
404
    table_options->set_has_user_set_auto_increment_value(true);
405
  else
406
    table_options->set_has_user_set_auto_increment_value(false);
407
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
408
  if (create_info->auto_increment_value)
409
    table_options->set_auto_increment_value(create_info->auto_increment_value);
410
1320.1.1 by Brian Aker
Light cleanup for references.
411
  for (uint32_t i= 0; i < keys; i++)
590.1.2 by Stewart Smith
store indexes in table definition protobuf
412
  {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
413
    message::Table::Index *idx;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
414
1320.1.1 by Brian Aker
Light cleanup for references.
415
    idx= table_proto.add_indexes();
590.1.2 by Stewart Smith
store indexes in table definition protobuf
416
417
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
418
           (key_info[i].comment.length > 0));
419
420
    idx->set_name(key_info[i].name);
421
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
422
    idx->set_key_length(key_info[i].key_length);
423
1372.1.3 by Brian Aker
Refactor for table message.
424
    if (is_primary_key_name(key_info[i].name))
590.1.2 by Stewart Smith
store indexes in table definition protobuf
425
      idx->set_is_primary(true);
426
    else
427
      idx->set_is_primary(false);
428
429
    switch(key_info[i].algorithm)
430
    {
431
    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'
432
      idx->set_type(message::Table::Index::HASH);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
433
      break;
434
435
    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'
436
      idx->set_type(message::Table::Index::BTREE);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
437
      break;
438
439
    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'
440
      idx->set_type(message::Table::Index::UNKNOWN_INDEX);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
441
      break;
442
443
    default:
444
      abort(); /* Somebody's brain broke. haven't added index type to proto */
445
    }
446
447
    if (key_info[i].flags & HA_NOSAME)
448
      idx->set_is_unique(true);
449
    else
450
      idx->set_is_unique(false);
451
1537 by Brian Aker
Remove dead options/rename Option and remove the update that we no longer
452
    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.
453
1372.1.3 by Brian Aker
Refactor for table message.
454
    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.
455
      index_options->set_key_block_size(key_info[i].block_size);
456
1372.1.3 by Brian Aker
Refactor for table message.
457
    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.
458
      index_options->set_pack_key(true);
459
1372.1.3 by Brian Aker
Refactor for table message.
460
    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.
461
      index_options->set_binary_pack_key(true);
462
1372.1.3 by Brian Aker
Refactor for table message.
463
    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.
464
      index_options->set_var_length_key(true);
465
1372.1.3 by Brian Aker
Refactor for table message.
466
    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.
467
      index_options->set_null_part_key(true);
468
1372.1.3 by Brian Aker
Refactor for table message.
469
    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.
470
      index_options->set_has_partial_segments(true);
471
1372.1.3 by Brian Aker
Refactor for table message.
472
    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.
473
      index_options->set_auto_generated_key(true);
474
475
    if (key_info[i].flags & HA_USES_COMMENT)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
476
    {
477
      uint32_t tmp_len;
478
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
479
						  key_info[i].comment.str,
480
						  key_info[i].comment.str +
481
						  key_info[i].comment.length,
482
						  TABLE_COMMENT_MAXLEN);
483
484
      if (tmp_len < key_info[i].comment.length)
485
      {
486
	my_error(ER_WRONG_STRING_LENGTH, MYF(0),
487
		 key_info[i].comment.str,"Index COMMENT",
488
		 (uint32_t) TABLE_COMMENT_MAXLEN);
2064.2.2 by Brian Aker
Formattting, etc.
489
	return true;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
490
      }
491
820.1.15 by Stewart Smith
Read (nearly the whole) index information (key and key parts) out of the proto, not FRM.
492
      idx->set_comment(key_info[i].comment.str);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
493
    }
1816.2.6 by Monty Taylor
Fixed three more ICC warnings.
494
    static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
495
                                               HA_USES_BLOCK_SIZE | 
496
                                               HA_BINARY_PACK_KEY |
497
                                               HA_VAR_LENGTH_PART |
498
                                               HA_NULL_PART_KEY | 
499
                                               HA_KEY_HAS_PART_KEY_SEG |
500
                                               HA_GENERATED_KEY |
501
                                               HA_USES_COMMENT);
502
    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.
503
      abort(); // Invalid (unknown) index flag.
590.1.2 by Stewart Smith
store indexes in table definition protobuf
504
505
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
506
    {
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
507
      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)
508
      const int fieldnr= key_info[i].key_part[j].fieldnr;
509
      int mbmaxlen= 1;
590.1.2 by Stewart Smith
store indexes in table definition protobuf
510
511
      idxpart= idx->add_index_part();
512
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)
513
      idxpart->set_fieldnr(fieldnr);
514
515
      if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
516
          || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
517
      {
518
        uint32_t collation_id;
519
520
        if (table_proto.field(fieldnr).string_options().has_collation_id())
521
          collation_id= table_proto.field(fieldnr).string_options().collation_id();
522
        else
523
          collation_id= table_proto.options().collation_id();
524
525
        const CHARSET_INFO *cs= get_charset(collation_id);
526
527
        mbmaxlen= cs->mbmaxlen;
528
      }
529
530
      idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
590.1.2 by Stewart Smith
store indexes in table definition protobuf
531
    }
532
  }
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
533
1608.1.2 by Brian Aker
Merge enum test
534
  if (not table_proto.IsInitialized())
535
  {
2017.2.1 by Brian Aker
Cleanup error messages around bad table definitions.
536
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
537
             table_proto.name().c_str(),
538
             table_proto.InitializationErrorString().c_str());
539
2064.2.2 by Brian Aker
Formattting, etc.
540
    return true;
1608.1.2 by Brian Aker
Merge enum test
541
  }
542
543
  /*
544
    Here we test to see if we can validate the Table Message before we continue. 
545
    We do this by serializing the protobuffer.
546
  */
547
  {
548
    string tmp_string;
549
550
    try {
551
      table_proto.SerializeToString(&tmp_string);
552
    }
553
554
    catch (...)
555
    {
556
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
2017.2.1 by Brian Aker
Cleanup error messages around bad table definitions.
557
               table_proto.name().c_str(),
558
               table_proto.InitializationErrorString().c_str());
1608.1.2 by Brian Aker
Merge enum test
559
2064.2.2 by Brian Aker
Formattting, etc.
560
      return true;
1608.1.2 by Brian Aker
Merge enum test
561
    }
562
  }
563
2064.2.2 by Brian Aker
Formattting, etc.
564
  return false;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
565
}
566
1 by brian
clean slate
567
/*
896.4.10 by Stewart Smith
some comment fixes in unireg.cc
568
  Create a table definition proto file and the tables
1 by brian
clean slate
569
570
  SYNOPSIS
571
    rea_create_table()
520.1.22 by Brian Aker
Second pass of thd cleanup
572
    session			Thread handler
1 by brian
clean slate
573
    path		Name of file (including database, without .frm)
574
    db			Data base name
575
    table_name		Table name
576
    create_info		create info parameters
577
    create_fields	Fields to create
578
    keys		number of keys to create
579
    key_info		Keys to create
580
581
  RETURN
582
    0  ok
583
    1  error
584
*/
585
1372.1.3 by Brian Aker
Refactor for table message.
586
bool rea_create_table(Session *session,
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
587
                      const identifier::Table &identifier,
1372.1.3 by Brian Aker
Refactor for table message.
588
                      message::Table &table_proto,
589
                      HA_CREATE_INFO *create_info,
590
                      List<CreateField> &create_fields,
1535 by Brian Aker
Rename of KEY to KeyInfo
591
                      uint32_t keys, KeyInfo *key_info)
1 by brian
clean slate
592
{
1685.2.13 by Brian Aker
Tiny cleanup in pass table_name where we no longer use it.
593
  assert(table_proto.has_name());
2187.7.6 by Brian Aker
This fixes the message such that the table inherits the no replication
594
595
  if (fill_table_proto(identifier,
596
                       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
597
                       keys, key_info))
2064.2.2 by Brian Aker
Formattting, etc.
598
  {
1372.1.3 by Brian Aker
Refactor for table message.
599
    return false;
2064.2.2 by Brian Aker
Formattting, etc.
600
  }
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).
601
1685.2.13 by Brian Aker
Tiny cleanup in pass table_name where we no longer use it.
602
  assert(table_proto.name() == identifier.getTableName());
603
2068.7.6 by Brian Aker
Fix interface for create table such that it issues error and returns state
604
  if (not plugin::StorageEngine::createTable(*session,
605
                                             identifier,
606
                                             table_proto))
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
607
  {
1372.1.3 by Brian Aker
Refactor for table message.
608
    return false;
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
609
  }
610
1372.1.3 by Brian Aker
Refactor for table message.
611
  return true;
1 by brian
clean slate
612
613
} /* rea_create_table */
1130.3.9 by Monty Taylor
Wrapped table_proto_write.cc code in namespace drizzled.
614
615
} /* 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.
616