1
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
* Derived from code Copyright (C) 2000-2004 MySQL AB
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
* Created by Barry Leslie on 8/27/08.
25
#include "discover_ms.h"
27
#include "mysql_priv.h"
28
#include "item_create.h"
30
#include "cslib/CSConfig.h"
31
#include "cslib/CSGlobal.h"
32
#include "cslib/CSThread.h"
36
#if MYSQL_VERSION_ID > 60005
37
#define DOT_STR(x) x.str
42
#define LOCK_OPEN_HACK_REQUIRED
44
#ifdef LOCK_OPEN_HACK_REQUIRED
45
///////////////////////////////
47
* Unfortunately I cannot use the standard mysql_create_table_no_lock() because it will lock "LOCK_open"
48
* which has already been locked while the server is performing table discovery. So I have added this hack
49
* in here to create my own version. The following macros will make the changes I need to get it to work.
50
* The actual function code has been copied here without changes.
52
* Its almost enough to make you want to cry. :(
54
//-----------------------------
56
#ifdef pthread_mutex_lock
57
#undef pthread_mutex_lock
60
#ifdef pthread_mutex_unlock
61
#undef pthread_mutex_unlock
64
#define mysql_create_table_no_lock hacked_mysql_create_table_no_lock
65
#define pthread_mutex_lock(l)
66
#define pthread_mutex_unlock(l)
68
#define check_engine(t, n, c) (0)
69
#define set_table_default_charset(t, c, d)
71
void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
72
uint32 *max_length, uint32 *tot_length);
74
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen);
75
uint build_table_filename(char *buff, size_t bufflen, const char *db,
76
const char *table_name, const char *ext, uint flags);
78
//////////////////////////////////////////////////////////
79
////// START OF CUT AND PASTES FROM sql_table.cc ////////
80
//////////////////////////////////////////////////////////
82
// sort_keys() cut and pasted directly from sql_table.cc.
83
static int sort_keys(KEY *a, KEY *b)
85
ulong a_flags= a->flags, b_flags= b->flags;
87
if (a_flags & HA_NOSAME)
89
if (!(b_flags & HA_NOSAME))
91
if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
93
/* Sort NOT NULL keys before other keys */
94
return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
96
if (a->name == primary_key_name)
98
if (b->name == primary_key_name)
100
/* Sort keys don't containing partial segments before others */
101
if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
102
return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
104
else if (b_flags & HA_NOSAME)
105
return 1; // Prefer b
107
if ((a_flags ^ b_flags) & HA_FULLTEXT)
109
return (a_flags & HA_FULLTEXT) ? 1 : -1;
112
Prefer original key order. usable_key_parts contains here
113
the original key position.
115
return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
116
(a->usable_key_parts > b->usable_key_parts) ? 1 :
120
// check_if_keyname_exists() cut and pasted directly from sql_table.cc.
122
check_if_keyname_exists(const char *name, KEY *start, KEY *end)
124
for (KEY *key=start ; key != end ; key++)
125
if (!my_strcasecmp(system_charset_info,name,key->name))
130
// make_unique_key_name() cut and pasted directly from sql_table.cc.
132
make_unique_key_name(const char *field_name,KEY *start,KEY *end)
134
char buff[MAX_FIELD_NAME],*buff_end;
136
if (!check_if_keyname_exists(field_name,start,end) &&
137
my_strcasecmp(system_charset_info,field_name,primary_key_name))
138
return (char*) field_name; // Use fieldname
139
buff_end=strmake(buff,field_name, sizeof(buff)-4);
142
Only 3 chars + '\0' left, so need to limit to 2 digit
143
This is ok as we can't have more than 100 keys anyway
145
for (uint i=2 ; i< 100; i++)
148
int10_to_str(i, buff_end+1, 10);
149
if (!check_if_keyname_exists(buff,start,end))
150
return sql_strdup(buff);
152
return (char*) "not_specified"; // Should never happen
156
// prepare_blob_field() cut and pasted directly from sql_table.cc.
157
static bool prepare_blob_field(THD *thd, Create_field *sql_field)
159
DBUG_ENTER("prepare_blob_field");
161
if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
162
!(sql_field->flags & BLOB_FLAG))
164
/* Convert long VARCHAR columns to TEXT or BLOB */
165
char warn_buff[MYSQL_ERRMSG_SIZE];
167
if (sql_field->def || (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES |
168
MODE_STRICT_ALL_TABLES)))
170
my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
171
MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
174
sql_field->sql_type= MYSQL_TYPE_BLOB;
175
sql_field->flags|= BLOB_FLAG;
176
snprintf(warn_buff, MYSQL_ERRMSG_SIZE, ER(ER_AUTO_CONVERT), sql_field->field_name,
177
(sql_field->charset == &my_charset_bin) ? "VARBINARY" : "VARCHAR",
178
(sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT");
179
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT,
183
if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
185
if (sql_field->sql_type == MYSQL_TYPE_BLOB)
187
/* The user has given a length to the blob column */
188
sql_field->sql_type= get_blob_type_from_length(sql_field->length);
189
sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
191
sql_field->length= 0;
196
//////////////////////////////
197
// mysql_prepare_create_table() cut and pasted directly from sql_table.cc.
199
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
200
Alter_info *alter_info,
203
handler *file, KEY **key_info_buffer,
204
uint *key_count, int select_field_count)
206
const char *key_name;
207
Create_field *sql_field,*dup_field;
208
uint field,null_fields,blob_columns,max_key_length;
209
ulong record_offset= 0;
211
KEY_PART_INFO *key_part_info;
212
int timestamps= 0, timestamps_with_niladic= 0;
214
int select_field_pos,auto_increment=0;
215
List<Create_field>::iterator it(alter_info->create_list);
216
List<Create_field>::iterator it2(alter_info->create_list);
217
uint total_uneven_bit_length= 0;
218
DBUG_ENTER("mysql_prepare_create_table");
220
select_field_pos= alter_info->create_list.elements - select_field_count;
221
null_fields=blob_columns=0;
222
create_info->varchar= 0;
223
max_key_length= file->max_key_length();
225
for (field_no=0; (sql_field=it++) ; field_no++)
227
CHARSET_INFO *save_cs;
230
Initialize length from its original value (number of characters),
231
which was set in the parser. This is necessary if we're
232
executing a prepared statement for the second time.
234
sql_field->length= sql_field->char_length;
235
if (!sql_field->charset)
236
sql_field->charset= create_info->default_table_charset;
238
table_charset is set in ALTER TABLE if we want change character set
239
for all varchar/char columns.
240
But the table charset must not affect the BLOB fields, so don't
241
allow to change my_charset_bin to somethig else.
243
if (create_info->table_charset && sql_field->charset != &my_charset_bin)
244
sql_field->charset= create_info->table_charset;
246
save_cs= sql_field->charset;
247
if ((sql_field->flags & BINCMP_FLAG) &&
248
!(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
249
MY_CS_BINSORT,MYF(0))))
252
strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
253
STRING_WITH_LEN("_bin"));
254
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
259
Convert the default value from client character
260
set into the column character set if necessary.
262
if (sql_field->def &&
263
save_cs != sql_field->def->collation.collation &&
264
(sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
265
sql_field->sql_type == MYSQL_TYPE_STRING ||
266
sql_field->sql_type == MYSQL_TYPE_SET ||
267
sql_field->sql_type == MYSQL_TYPE_ENUM))
270
Starting from 5.1 we work here with a copy of Create_field
271
created by the caller, not with the instance that was
272
originally created during parsing. It's OK to create
273
a temporary item and initialize with it a member of the
274
copy -- this item will be thrown away along with the copy
275
at the end of execution, and thus not introduce a dangling
276
pointer in the parsed tree of a prepared statement or a
277
stored procedure statement.
279
sql_field->def= sql_field->def->safe_charset_converter(save_cs);
281
if (sql_field->def == NULL)
283
/* Could not convert */
284
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
289
if (sql_field->sql_type == MYSQL_TYPE_SET ||
290
sql_field->sql_type == MYSQL_TYPE_ENUM)
293
CHARSET_INFO *cs= sql_field->charset;
294
TYPELIB *interval= sql_field->interval;
297
Create typelib from interval_list, and if necessary
298
convert strings from client character set to the
299
column character set.
304
Create the typelib in runtime memory - we will free the
305
occupied memory at the same time when we free this
306
sql_field -- at the end of execution.
308
interval= sql_field->interval= typelib(thd->mem_root,
309
sql_field->interval_list);
310
List<String>::iterator int_it(sql_field->interval_list);
313
int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
316
DBUG_ASSERT(comma_length > 0);
317
for (uint i= 0; (tmp= int_it++); i++)
320
if (String::needs_conversion(tmp->length(), tmp->charset(),
324
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
325
interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
327
interval->type_lengths[i]= conv.length();
330
// Strip trailing spaces.
331
lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
332
interval->type_lengths[i]);
333
interval->type_lengths[i]= lengthsp;
334
((uchar *)interval->type_names[i])[lengthsp]= '\0';
335
if (sql_field->sql_type == MYSQL_TYPE_SET)
337
if (cs->coll->instr(cs, interval->type_names[i],
338
interval->type_lengths[i],
339
comma_buf, comma_length, NULL, 0))
341
my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
346
sql_field->interval_list.empty(); // Don't need interval_list anymore
349
if (sql_field->sql_type == MYSQL_TYPE_SET)
352
if (sql_field->def != NULL)
357
String str, *def= sql_field->def->val_str(&str);
358
if (def == NULL) /* SQL "NULL" maps to NULL */
360
if ((sql_field->flags & NOT_NULL_FLAG) != 0)
362
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
366
/* else, NULL is an allowed value */
367
(void) find_set(interval, NULL, 0,
368
cs, ¬_used, ¬_used2, ¬_found);
372
(void) find_set(interval, def->ptr(), def->length(),
373
cs, ¬_used, ¬_used2, ¬_found);
378
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
382
calculate_interval_lengths(cs, interval, &dummy, &field_length);
383
sql_field->length= field_length + (interval->count - 1);
385
else /* MYSQL_TYPE_ENUM */
388
DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
389
if (sql_field->def != NULL)
391
String str, *def= sql_field->def->val_str(&str);
392
if (def == NULL) /* SQL "NULL" maps to NULL */
394
if ((sql_field->flags & NOT_NULL_FLAG) != 0)
396
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
400
/* else, the defaults yield the correct length for NULLs. */
404
def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
405
if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
407
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
412
calculate_interval_lengths(cs, interval, &field_length, &dummy);
413
sql_field->length= field_length;
415
set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
418
if (sql_field->sql_type == MYSQL_TYPE_BIT)
420
sql_field->pack_flag= FIELDFLAG_NUMBER;
421
if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
422
total_uneven_bit_length+= sql_field->length & 7;
424
sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
427
sql_field->create_length_to_internal_length();
428
if (prepare_blob_field(thd, sql_field))
431
if (!(sql_field->flags & NOT_NULL_FLAG))
434
if (check_column_name(sql_field->field_name))
436
my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
440
/* Check if we have used the same field name before */
441
for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
443
if (my_strcasecmp(system_charset_info,
444
sql_field->field_name,
445
dup_field->field_name) == 0)
448
If this was a CREATE ... SELECT statement, accept a field
449
redefinition if we are changing a field in the SELECT part
451
if (field_no < select_field_pos || dup_no >= select_field_pos)
453
my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
458
/* Field redefined */
459
sql_field->def= dup_field->def;
460
sql_field->sql_type= dup_field->sql_type;
461
sql_field->charset= (dup_field->charset ?
463
create_info->default_table_charset);
464
sql_field->length= dup_field->char_length;
465
sql_field->pack_length= dup_field->pack_length;
466
sql_field->key_length= dup_field->key_length;
467
sql_field->decimals= dup_field->decimals;
468
sql_field->create_length_to_internal_length();
469
sql_field->unireg_check= dup_field->unireg_check;
471
We're making one field from two, the result field will have
472
dup_field->flags as flags. If we've incremented null_fields
473
because of sql_field->flags, decrement it back.
475
if (!(sql_field->flags & NOT_NULL_FLAG))
477
sql_field->flags= dup_field->flags;
478
sql_field->interval= dup_field->interval;
479
it2.remove(); // Remove first (create) definition
485
/* Don't pack rows in old tables if the user has requested this */
486
if ((sql_field->flags & BLOB_FLAG) ||
487
sql_field->sql_type == MYSQL_TYPE_VARCHAR &&
488
create_info->row_type != ROW_TYPE_FIXED)
489
(*db_options)|= HA_OPTION_PACK_RECORD;
490
it2= alter_info->create_list;
493
/* record_offset will be increased with 'length-of-null-bits' later */
495
null_fields+= total_uneven_bit_length;
497
it= alter_info->create_list;
498
while ((sql_field=it++))
500
DBUG_ASSERT(sql_field->charset != 0);
502
if (prepare_create_field(sql_field, &blob_columns,
503
×tamps, ×tamps_with_niladic,
504
file->ha_table_flags()))
506
if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
507
create_info->varchar= TRUE;
508
sql_field->offset= record_offset;
509
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
511
record_offset+= sql_field->pack_length;
513
if (timestamps_with_niladic > 1)
515
my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
516
ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
519
if (auto_increment > 1)
521
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
524
if (auto_increment &&
525
(file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
527
my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
528
ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
532
if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
534
my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
541
List<Key>::iterator key_iterator(alter_info->key_list);
542
List<Key>::iterator key_iterator2(alter_info->key_list);
543
uint key_parts=0, fk_key_count=0;
544
bool primary_key=0,unique_key=0;
546
uint tmp, key_number;
547
/* special marker for keys to be ignored */
548
static char ignore_key[1];
550
/* Calculate number of key segements */
553
while ((key=key_iterator++))
555
DBUG_PRINT("info", ("key name: '%s' type: %d", key->DOT_STR(name) ? key->DOT_STR(name) :
556
"(none)" , key->type));
557
LEX_STRING key_name_str;
558
if (key->type == Key::FOREIGN_KEY)
561
Foreign_key *fk_key= (Foreign_key*) key;
562
if (fk_key->ref_columns.elements &&
563
fk_key->ref_columns.elements != fk_key->columns.elements)
565
my_error(ER_WRONG_FK_DEF, MYF(0),
566
(fk_key->DOT_STR(name) ? fk_key->DOT_STR(name) : "foreign key without name"),
567
ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
573
tmp=file->max_key_parts();
574
if (key->columns.elements > tmp)
576
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
579
key_name_str.str= (char*) key->DOT_STR(name);
580
key_name_str.length= key->DOT_STR(name) ? strlen(key->DOT_STR(name)) : 0;
581
if (check_string_char_length(&key_name_str, "", NAME_CHAR_LEN,
582
system_charset_info, 1))
584
my_error(ER_TOO_LONG_IDENT, MYF(0), key->DOT_STR(name));
587
key_iterator2= alter_info->key_list;
588
if (key->type != Key::FOREIGN_KEY)
590
while ((key2 = key_iterator2++) != key)
593
foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is
594
'generated', and a generated key is a prefix of the other key.
595
Then we do not need the generated shorter key.
597
if ((key2->type != Key::FOREIGN_KEY &&
598
key2->DOT_STR(name) != ignore_key &&
599
!foreign_key_prefix(key, key2)))
601
/* TODO: issue warning message */
602
/* mark that the generated key should be ignored */
603
if (!key2->generated ||
604
(key->generated && key->columns.elements <
605
key2->columns.elements))
606
key->DOT_STR(name)= ignore_key;
609
key2->DOT_STR(name)= ignore_key;
610
key_parts-= key2->columns.elements;
617
if (key->DOT_STR(name) != ignore_key)
618
key_parts+=key->columns.elements;
621
if (key->DOT_STR(name) && !tmp_table && (key->type != Key::PRIMARY) &&
622
!my_strcasecmp(system_charset_info,key->DOT_STR(name),primary_key_name))
624
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->DOT_STR(name));
628
tmp=file->max_keys();
629
if (*key_count > tmp)
631
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
635
(*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));
636
key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
637
if (!*key_info_buffer || ! key_part_info)
638
DBUG_RETURN(TRUE); // Out of memory
640
key_iterator= alter_info->key_list;
642
for (; (key=key_iterator++) ; key_number++)
645
Key_part_spec *column;
647
if (key->DOT_STR(name) == ignore_key)
649
/* ignore redundant keys */
652
while (key && key->DOT_STR(name) == ignore_key);
662
key_info->flags= HA_FULLTEXT;
663
if ((key_info->parser_name= &key->key_create_info.parser_name)->str)
664
key_info->flags|= HA_USES_PARSER;
666
key_info->parser_name= 0;
670
key_info->flags= HA_SPATIAL;
673
my_error(ER_FEATURE_DISABLED, MYF(0),
674
sym_group_geom.name, sym_group_geom.needed_define);
677
case Key::FOREIGN_KEY:
678
key_number--; // Skip this key
681
key_info->flags = HA_NOSAME;
685
key_info->flags|= HA_GENERATED_KEY;
687
key_info->key_parts=(uint8) key->columns.elements;
688
key_info->key_part=key_part_info;
689
key_info->usable_key_parts= key_number;
690
key_info->algorithm= key->key_create_info.algorithm;
692
if (key->type == Key::FULLTEXT)
694
if (!(file->ha_table_flags() & HA_CAN_FULLTEXT))
696
my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT),
702
Make SPATIAL to be RTREE by default
703
SPATIAL only on BLOB or at least BINARY, this
704
actually should be replaced by special GEOM type
705
in near future when new frm file is ready
706
checking for proper key parts number:
709
/* TODO: Add proper checks if handler supports key_type and algorithm */
710
if (key_info->flags & HA_SPATIAL)
712
if (!(file->ha_table_flags() & HA_CAN_RTREEKEYS))
714
my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS),
718
if (key_info->key_parts != 1)
720
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
724
else if (key_info->algorithm == HA_KEY_ALG_RTREE)
726
#ifdef HAVE_RTREE_KEYS
727
if ((key_info->key_parts & 1) == 1)
729
my_error(ER_WRONG_ARGUMENTS, MYF(0), "RTREE INDEX");
732
/* TODO: To be deleted */
733
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "RTREE INDEX");
736
my_error(ER_FEATURE_DISABLED, MYF(0),
737
sym_group_rtree.name, sym_group_rtree.needed_define);
742
/* Take block size from key part or table part */
744
TODO: Add warning if block size changes. We can't do it here, as
745
this may depend on the size of the key
747
key_info->block_size= (key->key_create_info.block_size ?
748
key->key_create_info.block_size :
749
create_info->key_block_size);
751
if (key_info->block_size)
752
key_info->flags|= HA_USES_BLOCK_SIZE;
754
List<Key_part_spec>::iterator cols(key->columns);
755
List<Key_part_spec>::iterator cols2(key->columns);
756
CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
757
for (uint column_nr=0 ; (column=cols++) ; column_nr++)
760
Key_part_spec *dup_column;
762
it= alter_info->create_list;
764
while ((sql_field=it++) &&
765
my_strcasecmp(system_charset_info,
766
column->DOT_STR(field_name),
767
sql_field->field_name))
771
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name);
774
while ((dup_column= cols2++) != column)
776
if (!my_strcasecmp(system_charset_info,
777
column->DOT_STR(field_name), dup_column->DOT_STR(field_name)))
779
my_printf_error(ER_DUP_FIELDNAME,
780
ER(ER_DUP_FIELDNAME),MYF(0),
786
if (key->type == Key::FULLTEXT)
788
if ((sql_field->sql_type != MYSQL_TYPE_STRING &&
789
sql_field->sql_type != MYSQL_TYPE_VARCHAR &&
790
!f_is_blob(sql_field->pack_flag)) ||
791
sql_field->charset == &my_charset_bin ||
792
sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
793
(ft_key_charset && sql_field->charset != ft_key_charset))
795
my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name);
798
ft_key_charset=sql_field->charset;
800
for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
801
code anyway, and 0 (set to column width later) for char's. it has
802
to be correct col width for char's, as char data are not prefixed
803
with length (unlike blobs, where ft code takes data length from a
804
data prefix, ignoring column->length).
806
column->length=test(f_is_blob(sql_field->pack_flag));
810
column->length*= sql_field->charset->mbmaxlen;
812
if (key->type == Key::SPATIAL && column->length)
814
my_error(ER_WRONG_SUB_KEY, MYF(0));
818
if (f_is_blob(sql_field->pack_flag) ||
819
(f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
821
if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
823
my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name);
826
if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
831
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name);
836
if (key->type == Key::SPATIAL)
841
4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
842
Lately we'll extend this code to support more dimensions
844
column->length= 4*sizeof(double);
848
if (!(sql_field->flags & NOT_NULL_FLAG))
850
if (key->type == Key::PRIMARY)
852
/* Implicitly set primary key fields to NOT NULL for ISO conf. */
853
sql_field->flags|= NOT_NULL_FLAG;
854
sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
859
key_info->flags|= HA_NULL_PART_KEY;
860
if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
862
my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name);
865
if (key->type == Key::SPATIAL)
867
my_message(ER_SPATIAL_CANT_HAVE_NULL,
868
ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
873
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
875
if (column_nr == 0 || (file->ha_table_flags() & HA_AUTO_PART_KEY))
876
auto_increment--; // Field is used
880
key_part_info->fieldnr= field;
881
key_part_info->offset= (uint16) sql_field->offset;
882
key_part_info->key_type=sql_field->pack_flag;
883
length= sql_field->key_length;
887
if (f_is_blob(sql_field->pack_flag))
889
if ((length=column->length) > max_key_length ||
890
length > file->max_key_part_length())
892
length=min(max_key_length, file->max_key_part_length());
893
if (key->type == Key::MULTIPLE)
895
/* not a critical problem */
896
char warn_buff[MYSQL_ERRMSG_SIZE];
897
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
899
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
900
ER_TOO_LONG_KEY, warn_buff);
901
/* Align key length to multibyte char boundary */
902
length-= length % sql_field->charset->mbmaxlen;
906
my_error(ER_TOO_LONG_KEY,MYF(0),length);
911
else if (!f_is_geom(sql_field->pack_flag) &&
912
(column->length > length ||
913
!Field::type_can_have_key_part (sql_field->sql_type) ||
914
((f_is_packed(sql_field->pack_flag) ||
915
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
916
(key_info->flags & HA_NOSAME))) &&
917
column->length != length)))
919
my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
922
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
923
length=column->length;
925
else if (length == 0)
927
my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name);
930
if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
932
length= file->max_key_part_length();
933
if (key->type == Key::MULTIPLE)
935
/* not a critical problem */
936
char warn_buff[MYSQL_ERRMSG_SIZE];
937
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
939
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
940
ER_TOO_LONG_KEY, warn_buff);
941
/* Align key length to multibyte char boundary */
942
length-= length % sql_field->charset->mbmaxlen;
946
my_error(ER_TOO_LONG_KEY,MYF(0),length);
950
key_part_info->length=(uint16) length;
951
/* Use packed keys for long strings on the first column */
952
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
953
(length >= KEY_DEFAULT_PACK_LENGTH &&
954
(sql_field->sql_type == MYSQL_TYPE_STRING ||
955
sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
956
sql_field->pack_flag & FIELDFLAG_BLOB)))
958
if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB) ||
959
sql_field->sql_type == MYSQL_TYPE_VARCHAR)
960
key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
962
key_info->flags|= HA_PACK_KEY;
964
/* Check if the key segment is partial, set the key flag accordingly */
965
if (length != sql_field->key_length)
966
key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
971
/* Create the key name based on the first column (if not given) */
974
if (key->type == Key::PRIMARY)
978
my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
982
key_name=primary_key_name;
985
else if (!(key_name = key->DOT_STR(name)))
986
key_name=make_unique_key_name(sql_field->field_name,
987
*key_info_buffer, key_info);
988
if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
990
my_error(ER_DUP_KEYNAME, MYF(0), key_name);
993
key_info->name=(char*) key_name;
996
if (!key_info->name || check_column_name(key_info->name))
998
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1001
if (!(key_info->flags & HA_NULL_PART_KEY))
1003
key_info->key_length=(uint16) key_length;
1004
if (key_length > max_key_length && key->type != Key::FULLTEXT)
1006
my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1011
if (!unique_key && !primary_key &&
1012
(file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
1014
my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1017
if (auto_increment > 0)
1019
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1022
/* Sort keys in optimized order */
1023
my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
1024
(qsort_cmp) sort_keys);
1025
create_info->null_bits= null_fields;
1028
it= alter_info->create_list;
1029
while ((sql_field=it++))
1031
Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1033
if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
1035
sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
1036
(sql_field->flags & NOT_NULL_FLAG) &&
1037
(type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1040
An error should be reported if:
1041
- NO_ZERO_DATE SQL mode is active;
1042
- there is no explicit DEFAULT clause (default column value);
1043
- this is a TIMESTAMP column;
1044
- the column is not NULL;
1045
- this is not the DEFAULT CURRENT_TIMESTAMP column.
1047
In other words, an error should be reported if
1048
- NO_ZERO_DATE SQL mode is active;
1049
- the column definition is equivalent to
1050
'column_name TIMESTAMP DEFAULT 0'.
1053
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1061
//////////////////////////////
1062
// mysql_create_table_no_lock() cut and pasted directly from sql_table.cc. (I did make is static after copying it.)
1064
static bool mysql_create_table_no_lock(THD *thd,
1065
const char *db, const char *table_name,
1066
HA_CREATE_INFO *create_info,
1067
Alter_info *alter_info,
1068
bool internal_tmp_table,
1069
uint select_field_count)
1071
char path[FN_REFLEN];
1074
uint db_options, key_count;
1075
KEY *key_info_buffer;
1078
DBUG_ENTER("mysql_create_table_no_lock");
1079
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
1080
db, table_name, internal_tmp_table));
1083
/* Check for duplicate fields and check type of table to create */
1084
if (!alter_info->create_list.elements)
1086
my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1090
if (check_engine(thd, table_name, create_info))
1092
db_options= create_info->table_options;
1093
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1094
db_options|=HA_OPTION_PACK_RECORD;
1095
alias= table_case_name(create_info, table_name);
1097
/* PMC - Done to avoid getting the partition handler by mistake! */
1098
if (!(file= new (thd->mem_root) ha_pbms(pbms_hton, NULL)))
1100
mem_alloc_error(sizeof(handler));
1106
set_table_default_charset(thd, create_info, (char*) db);
1108
if (mysql_prepare_create_table(thd, create_info, alter_info,
1111
&key_info_buffer, &key_count,
1112
select_field_count))
1115
/* Check if table exists */
1116
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1118
path_length= build_tmptable_filename(thd, path, sizeof(path));
1119
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1124
/* check if the table name contains FN_DEVCHAR when defined */
1125
if (strchr(alias, FN_DEVCHAR))
1127
my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
1131
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
1132
internal_tmp_table ? FN_IS_TMP : 0);
1135
/* Check if table already exists */
1136
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1137
find_temporary_table(thd, db, table_name))
1139
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1141
create_info->table_existed= 1; // Mark that table existed
1142
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1143
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1148
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
1152
pthread_mutex_lock(&LOCK_open);
1153
if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1155
if (!access(path,F_OK))
1157
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1159
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
1160
goto unlock_and_end;
1163
We don't assert here, but check the result, because the table could be
1164
in the table definition cache and in the same time the .frm could be
1165
missing from the disk, in case of manual intervention which deletes
1166
the .frm file. The user has to use FLUSH TABLES; to clear the cache.
1167
Then she could create the table. This case is pretty obscure and
1168
therefore we don't introduce a new error message only for it.
1170
if (get_cached_table_share(db, alias))
1172
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
1173
goto unlock_and_end;
1178
Check that table with given name does not already
1179
exist in any storage engine. In such a case it should
1180
be discovered and the error ER_TABLE_EXISTS_ERROR be returned
1181
unless user specified CREATE TABLE IF EXISTS
1182
The LOCK_open mutex has been locked to make sure no
1183
one else is attempting to discover the table. Since
1184
it's not on disk as a frm file, no one could be using it!
1186
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1188
bool create_if_not_exists =
1189
create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1190
int retcode = ha_table_exists_in_engine(thd, db, table_name);
1191
DBUG_PRINT("info", ("exists_in_engine: %"PRIu32"",retcode));
1194
case HA_ERR_NO_SUCH_TABLE:
1195
/* Normal case, no table exists. we can go and create it */
1197
case HA_ERR_TABLE_EXIST:
1198
DBUG_PRINT("info", ("Table existed in handler"));
1200
if (create_if_not_exists)
1202
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
1203
goto unlock_and_end;
1206
DBUG_PRINT("info", ("error: %"PRIu32" from storage engine", retcode));
1207
my_error(retcode, MYF(0),table_name);
1208
goto unlock_and_end;
1212
thd_proc_info(thd, "creating table");
1213
create_info->table_existed= 0; // Mark that table is created
1215
create_info->table_options=db_options;
1217
path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1218
if (rea_create_table(thd, path, db, table_name,
1219
create_info, alter_info->create_list,
1220
key_count, key_info_buffer, file))
1221
goto unlock_and_end;
1223
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1225
/* Open table and put in temporary table list */
1226
#if MYSQL_VERSION_ID > 60005
1227
if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
1229
if (!(open_temporary_table(thd, path, db, table_name, 1)))
1232
#if MYSQL_VERSION_ID > 60005
1233
(void) rm_temporary_table(create_info->db_type, path, false);
1235
(void) rm_temporary_table(create_info->db_type, path);
1237
goto unlock_and_end;
1239
thd->thread_specific_used= TRUE;
1243
Don't write statement if:
1244
- It is an internal temporary table,
1245
- Row-based logging is used and it we are creating a temporary table, or
1246
- The binary log is not open.
1247
Otherwise, the statement shall be binlogged.
1249
if (!internal_tmp_table &&
1250
(!thd->current_stmt_binlog_row_based ||
1251
(thd->current_stmt_binlog_row_based &&
1252
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1253
#if MYSQL_VERSION_ID > 50140
1254
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
1256
write_bin_log(thd, TRUE, thd->query, thd->query_length);
1260
pthread_mutex_unlock(&LOCK_open);
1263
thd_proc_info(thd, "After create");
1269
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1270
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1272
create_info->table_existed= 1; // Mark that table existed
1273
goto unlock_and_end;
1276
////////////////////////////////////////////////////////
1277
////// END OF CUT AND PASTES FROM sql_table.cc ////////
1278
////////////////////////////////////////////////////////
1280
#endif // LOCK_OPEN_HACK_REQUIRED
1283
//------------------------------
1284
int ms_create_table_frm(handlerton *hton, THD* thd, const char *db, const char *name, DT_FIELD_INFO *info, DT_KEY_INFO *keys, uchar **frmblob, size_t *frmlen )
1286
char file_name[FN_REFLEN];
1287
int err = 1, delete_frm = 0;
1288
char field_length_buffer[12], *field_length_ptr;
1289
LEX *save_lex= thd->lex, mylex;
1291
memset(&mylex.create_info, 0, sizeof(HA_CREATE_INFO));
1296
/* setup the create info */
1297
mylex.create_info.db_type = hton;
1298
mylex.create_info.frm_only = 1;
1299
mylex.create_info.default_table_charset = system_charset_info;
1301
/* setup the column info. */
1302
while (info->field_name) {
1303
LEX_STRING field_name, comment;
1304
field_name.str = (char*)(info->field_name);
1305
field_name.length = strlen(info->field_name);
1307
comment.str = (char*)(info->comment);
1308
comment.length = strlen(info->comment);
1310
if (info->field_length) {
1311
snprintf(field_length_buffer, 12, "%d", info->field_length);
1312
field_length_ptr = field_length_buffer;
1314
field_length_ptr = NULL;
1316
if (add_field_to_list(thd, &field_name, info->field_type, field_length_ptr, info->field_decimal_length,
1318
#if MYSQL_VERSION_ID > 60005
1320
COLUMN_FORMAT_TYPE_FIXED,
1322
NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/,
1323
NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/))
1332
while (keys->key_name) {
1335
enum Key::Keytype type;
1336
List<Key_part_spec> col_list;
1338
while (keys->key_columns[i]) {
1339
lex.str = (char *)(keys->key_columns[i++]);
1340
lex.length = strlen(lex.str);
1341
col_list.push_back(new Key_part_spec(lex, 0));
1342
//col_list.push_back(new Key_part_spec(keys->key_columns[i++], 0));
1345
switch (keys->key_type) {
1347
type = Key::PRIMARY;
1349
case UNIQUE_KEY_FLAG:
1352
case MULTIPLE_KEY_FLAG:
1353
type = Key::MULTIPLE;
1357
key= new Key(type, keys->key_name, strlen(keys->key_name),
1358
&default_key_create_info,
1360
mylex.alter_info.key_list.push_back(key);
1367
/* Create an internal temp table */
1368
if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0))
1372
/* Read the FRM file. */
1373
build_table_filename(file_name, sizeof(file_name), db, name, "", FN_IS_TMP);
1374
if (readfrm(file_name, frmblob, frmlen))
1381
thd->lex = save_lex;
1384
build_table_filename(file_name, sizeof(file_name), db, name, reg_ext, FN_IS_TMP);
1385
my_delete(file_name, MYF(0));