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 (!system_charset_info->strcasecmp(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=strdup(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_st *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
strdup(strdup(tmp, save_cs->csname, sizeof(tmp)-4), STRING_WITH_LEN("_bin"));
253
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
258
Convert the default value from client character
259
set into the column character set if necessary.
261
if (sql_field->def &&
262
save_cs != sql_field->def->collation.collation &&
263
(sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
264
sql_field->sql_type == MYSQL_TYPE_STRING ||
265
sql_field->sql_type == MYSQL_TYPE_SET ||
266
sql_field->sql_type == MYSQL_TYPE_ENUM))
269
Starting from 5.1 we work here with a copy of Create_field
270
created by the caller, not with the instance that was
271
originally created during parsing. It's OK to create
272
a temporary item and initialize with it a member of the
273
copy -- this item will be thrown away along with the copy
274
at the end of execution, and thus not introduce a dangling
275
pointer in the parsed tree of a prepared statement or a
276
stored procedure statement.
278
sql_field->def= sql_field->def->safe_charset_converter(save_cs);
280
if (sql_field->def == NULL)
282
/* Could not convert */
283
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
288
if (sql_field->sql_type == MYSQL_TYPE_SET ||
289
sql_field->sql_type == MYSQL_TYPE_ENUM)
292
charset_info_st *cs= sql_field->charset;
293
TYPELIB *interval= sql_field->interval;
296
Create typelib from interval_list, and if necessary
297
convert strings from client character set to the
298
column character set.
303
Create the typelib in runtime memory - we will free the
304
occupied memory at the same time when we free this
305
sql_field -- at the end of execution.
307
interval= sql_field->interval= typelib(thd->mem_root,
308
sql_field->interval_list);
309
List<String>::iterator int_it(sql_field->interval_list);
312
int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
315
DBUG_ASSERT(comma_length > 0);
316
for (uint i= 0; (tmp= int_it++); i++)
319
if (String::needs_conversion(tmp->length(), tmp->charset(), cs))
322
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
323
interval->type_names[i]= strdup(thd->mem_root, conv.ptr(),
325
interval->type_lengths[i]= conv.length();
328
// Strip trailing spaces.
329
lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
330
interval->type_lengths[i]);
331
interval->type_lengths[i]= lengthsp;
332
((uchar *)interval->type_names[i])[lengthsp]= '\0';
333
if (sql_field->sql_type == MYSQL_TYPE_SET)
335
if (cs->coll->instr(cs, interval->type_names[i],
336
interval->type_lengths[i],
337
comma_buf, comma_length, NULL, 0))
339
my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
344
sql_field->interval_list.empty(); // Don't need interval_list anymore
347
if (sql_field->sql_type == MYSQL_TYPE_SET)
350
if (sql_field->def != NULL)
355
String str, *def= sql_field->def->val_str(&str);
356
if (def == NULL) /* SQL "NULL" maps to NULL */
358
if ((sql_field->flags & NOT_NULL_FLAG) != 0)
360
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
364
/* else, NULL is an allowed value */
365
(void) find_set(interval, NULL, 0,
366
cs, ¬_used, ¬_used2, ¬_found);
370
(void) find_set(interval, def->ptr(), def->length(),
371
cs, ¬_used, ¬_used2, ¬_found);
376
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
380
calculate_interval_lengths(cs, interval, &dummy, &field_length);
381
sql_field->length= field_length + (interval->count - 1);
383
else /* MYSQL_TYPE_ENUM */
386
DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
387
if (sql_field->def != NULL)
389
String str, *def= sql_field->def->val_str(&str);
390
if (def == NULL) /* SQL "NULL" maps to NULL */
392
if ((sql_field->flags & NOT_NULL_FLAG) != 0)
394
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
398
/* else, the defaults yield the correct length for NULLs. */
402
def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
403
if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
405
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
410
calculate_interval_lengths(cs, interval, &field_length, &dummy);
411
sql_field->length= field_length;
413
set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
416
if (sql_field->sql_type == MYSQL_TYPE_BIT)
418
sql_field->pack_flag= FIELDFLAG_NUMBER;
419
if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
420
total_uneven_bit_length+= sql_field->length & 7;
422
sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
425
sql_field->create_length_to_internal_length();
426
if (prepare_blob_field(thd, sql_field))
429
if (!(sql_field->flags & NOT_NULL_FLAG))
432
if (check_column_name(sql_field->field_name))
434
my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
438
/* Check if we have used the same field name before */
439
for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
441
if (system_charset_info->strcasecmp(sql_field->field_name, dup_field->field_name) == 0)
444
If this was a CREATE ... SELECT statement, accept a field
445
redefinition if we are changing a field in the SELECT part
447
if (field_no < select_field_pos || dup_no >= select_field_pos)
449
my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
454
/* Field redefined */
455
sql_field->def= dup_field->def;
456
sql_field->sql_type= dup_field->sql_type;
457
sql_field->charset= (dup_field->charset ?
459
create_info->default_table_charset);
460
sql_field->length= dup_field->char_length;
461
sql_field->pack_length= dup_field->pack_length;
462
sql_field->key_length= dup_field->key_length;
463
sql_field->decimals= dup_field->decimals;
464
sql_field->create_length_to_internal_length();
465
sql_field->unireg_check= dup_field->unireg_check;
467
We're making one field from two, the result field will have
468
dup_field->flags as flags. If we've incremented null_fields
469
because of sql_field->flags, decrement it back.
471
if (!(sql_field->flags & NOT_NULL_FLAG))
473
sql_field->flags= dup_field->flags;
474
sql_field->interval= dup_field->interval;
475
it2.remove(); // Remove first (create) definition
481
/* Don't pack rows in old tables if the user has requested this */
482
if ((sql_field->flags & BLOB_FLAG) ||
483
sql_field->sql_type == MYSQL_TYPE_VARCHAR &&
484
create_info->row_type != ROW_TYPE_FIXED)
485
(*db_options)|= HA_OPTION_PACK_RECORD;
486
it2= alter_info->create_list;
489
/* record_offset will be increased with 'length-of-null-bits' later */
491
null_fields+= total_uneven_bit_length;
493
it= alter_info->create_list;
494
while ((sql_field=it++))
496
DBUG_ASSERT(sql_field->charset != 0);
498
if (prepare_create_field(sql_field, &blob_columns,
499
×tamps, ×tamps_with_niladic,
500
file->ha_table_flags()))
502
if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
503
create_info->varchar= TRUE;
504
sql_field->offset= record_offset;
505
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
507
record_offset+= sql_field->pack_length;
509
if (timestamps_with_niladic > 1)
511
my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
512
ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
515
if (auto_increment > 1)
517
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
520
if (auto_increment &&
521
(file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
523
my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
524
ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
528
if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
530
my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
537
List<Key>::iterator key_iterator(alter_info->key_list);
538
List<Key>::iterator key_iterator2(alter_info->key_list);
539
uint key_parts=0, fk_key_count=0;
540
bool primary_key=0,unique_key=0;
542
uint tmp, key_number;
543
/* special marker for keys to be ignored */
544
static char ignore_key[1];
546
/* Calculate number of key segements */
549
while ((key=key_iterator++))
551
DBUG_PRINT("info", ("key name: '%s' type: %d", key->DOT_STR(name) ? key->DOT_STR(name) :
552
"(none)" , key->type));
553
lex_string_t key_name_str;
554
if (key->type == Key::FOREIGN_KEY)
557
Foreign_key *fk_key= (Foreign_key*) key;
558
if (fk_key->ref_columns.elements &&
559
fk_key->ref_columns.elements != fk_key->columns.elements)
561
my_error(ER_WRONG_FK_DEF, MYF(0),
562
(fk_key->DOT_STR(name) ? fk_key->DOT_STR(name) : "foreign key without name"),
563
ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
569
tmp=file->max_key_parts();
570
if (key->columns.elements > tmp)
572
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
575
key_name_str.str= (char*) key->DOT_STR(name);
576
key_name_str.length= key->DOT_STR(name) ? strlen(key->DOT_STR(name)) : 0;
577
if (check_string_char_length(&key_name_str, "", NAME_CHAR_LEN,
578
system_charset_info, 1))
580
my_error(ER_TOO_LONG_IDENT, MYF(0), key->DOT_STR(name));
583
key_iterator2= alter_info->key_list;
584
if (key->type != Key::FOREIGN_KEY)
586
while ((key2 = key_iterator2++) != key)
589
foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is
590
'generated', and a generated key is a prefix of the other key.
591
Then we do not need the generated shorter key.
593
if ((key2->type != Key::FOREIGN_KEY &&
594
key2->DOT_STR(name) != ignore_key &&
595
!foreign_key_prefix(key, key2)))
597
/* TODO: issue warning message */
598
/* mark that the generated key should be ignored */
599
if (!key2->generated ||
600
(key->generated && key->columns.elements <
601
key2->columns.elements))
602
key->DOT_STR(name)= ignore_key;
605
key2->DOT_STR(name)= ignore_key;
606
key_parts-= key2->columns.elements;
613
if (key->DOT_STR(name) != ignore_key)
614
key_parts+=key->columns.elements;
617
if (key->DOT_STR(name) && !tmp_table && (key->type != Key::PRIMARY) &&
618
!system_charset_info->strcasecmp(key->DOT_STR(name),primary_key_name))
620
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->DOT_STR(name));
624
tmp=file->max_keys();
625
if (*key_count > tmp)
627
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
631
(*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));
632
key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
633
if (!*key_info_buffer || ! key_part_info)
634
DBUG_RETURN(TRUE); // Out of memory
636
key_iterator= alter_info->key_list;
638
for (; (key=key_iterator++) ; key_number++)
641
Key_part_spec *column;
643
if (key->DOT_STR(name) == ignore_key)
645
/* ignore redundant keys */
648
while (key && key->DOT_STR(name) == ignore_key);
658
key_info->flags= HA_FULLTEXT;
659
if ((key_info->parser_name= &key->key_create_info.parser_name)->data())
660
key_info->flags|= HA_USES_PARSER;
662
key_info->parser_name= 0;
666
key_info->flags= HA_SPATIAL;
669
my_error(ER_FEATURE_DISABLED, MYF(0),
670
sym_group_geom.name, sym_group_geom.needed_define);
673
case Key::FOREIGN_KEY:
674
key_number--; // Skip this key
677
key_info->flags = HA_NOSAME;
681
key_info->flags|= HA_GENERATED_KEY;
683
key_info->key_parts=(uint8) key->columns.elements;
684
key_info->key_part=key_part_info;
685
key_info->usable_key_parts= key_number;
686
key_info->algorithm= key->key_create_info.algorithm;
688
if (key->type == Key::FULLTEXT)
690
if (!(file->ha_table_flags() & HA_CAN_FULLTEXT))
692
my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT),
698
Make SPATIAL to be RTREE by default
699
SPATIAL only on BLOB or at least BINARY, this
700
actually should be replaced by special GEOM type
701
in near future when new frm file is ready
702
checking for proper key parts number:
705
/* TODO: Add proper checks if handler supports key_type and algorithm */
706
if (key_info->flags & HA_SPATIAL)
708
if (!(file->ha_table_flags() & HA_CAN_RTREEKEYS))
710
my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS),
714
if (key_info->key_parts != 1)
716
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
720
else if (key_info->algorithm == HA_KEY_ALG_RTREE)
722
#ifdef HAVE_RTREE_KEYS
723
if ((key_info->key_parts & 1) == 1)
725
my_error(ER_WRONG_ARGUMENTS, MYF(0), "RTREE INDEX");
728
/* TODO: To be deleted */
729
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "RTREE INDEX");
732
my_error(ER_FEATURE_DISABLED, MYF(0),
733
sym_group_rtree.name, sym_group_rtree.needed_define);
738
/* Take block size from key part or table part */
740
TODO: Add warning if block size changes. We can't do it here, as
741
this may depend on the size of the key
743
key_info->block_size= (key->key_create_info.block_size ?
744
key->key_create_info.block_size :
745
create_info->key_block_size);
747
if (key_info->block_size)
748
key_info->flags|= HA_USES_BLOCK_SIZE;
750
List<Key_part_spec>::iterator cols(key->columns);
751
List<Key_part_spec>::iterator cols2(key->columns);
752
charset_info_st *ft_key_charset=0; // for FULLTEXT
753
for (uint column_nr=0 ; (column=cols++) ; column_nr++)
756
Key_part_spec *dup_column;
758
it= alter_info->create_list;
760
while ((sql_field=it++) && system_charset_info->strcasecmp(column->DOT_STR(field_name), sql_field->field_name))
764
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name);
767
while ((dup_column= cols2++) != column)
769
if (!system_charset_info->strcasecmp(column->DOT_STR(field_name), dup_column->DOT_STR(field_name)))
771
my_printf_error(ER_DUP_FIELDNAME,
772
ER(ER_DUP_FIELDNAME),MYF(0),
778
if (key->type == Key::FULLTEXT)
780
if ((sql_field->sql_type != MYSQL_TYPE_STRING &&
781
sql_field->sql_type != MYSQL_TYPE_VARCHAR &&
782
!f_is_blob(sql_field->pack_flag)) ||
783
sql_field->charset == &my_charset_bin ||
784
sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
785
(ft_key_charset && sql_field->charset != ft_key_charset))
787
my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name);
790
ft_key_charset=sql_field->charset;
792
for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
793
code anyway, and 0 (set to column width later) for char's. it has
794
to be correct col width for char's, as char data are not prefixed
795
with length (unlike blobs, where ft code takes data length from a
796
data prefix, ignoring column->length).
798
column->length=test(f_is_blob(sql_field->pack_flag));
802
column->length*= sql_field->charset->mbmaxlen;
804
if (key->type == Key::SPATIAL && column->length)
806
my_error(ER_WRONG_SUB_KEY, MYF(0));
810
if (f_is_blob(sql_field->pack_flag) ||
811
(f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
813
if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
815
my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name);
818
if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
823
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name);
828
if (key->type == Key::SPATIAL)
833
4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
834
Lately we'll extend this code to support more dimensions
836
column->length= 4*sizeof(double);
840
if (!(sql_field->flags & NOT_NULL_FLAG))
842
if (key->type == Key::PRIMARY)
844
/* Implicitly set primary key fields to NOT NULL for ISO conf. */
845
sql_field->flags|= NOT_NULL_FLAG;
846
sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
851
key_info->flags|= HA_NULL_PART_KEY;
852
if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
854
my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name);
857
if (key->type == Key::SPATIAL)
859
my_message(ER_SPATIAL_CANT_HAVE_NULL,
860
ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
865
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
867
if (column_nr == 0 || (file->ha_table_flags() & HA_AUTO_PART_KEY))
868
auto_increment--; // Field is used
872
key_part_info->fieldnr= field;
873
key_part_info->offset= (uint16) sql_field->offset;
874
key_part_info->key_type=sql_field->pack_flag;
875
length= sql_field->key_length;
879
if (f_is_blob(sql_field->pack_flag))
881
if ((length=column->length) > max_key_length ||
882
length > file->max_key_part_length())
884
length=min(max_key_length, file->max_key_part_length());
885
if (key->type == Key::MULTIPLE)
887
/* not a critical problem */
888
char warn_buff[MYSQL_ERRMSG_SIZE];
889
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
891
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
892
ER_TOO_LONG_KEY, warn_buff);
893
/* Align key length to multibyte char boundary */
894
length-= length % sql_field->charset->mbmaxlen;
898
my_error(ER_TOO_LONG_KEY,MYF(0),length);
903
else if (!f_is_geom(sql_field->pack_flag) &&
904
(column->length > length ||
905
!Field::type_can_have_key_part (sql_field->sql_type) ||
906
((f_is_packed(sql_field->pack_flag) ||
907
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
908
(key_info->flags & HA_NOSAME))) &&
909
column->length != length)))
911
my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
914
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
915
length=column->length;
917
else if (length == 0)
919
my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name);
922
if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
924
length= file->max_key_part_length();
925
if (key->type == Key::MULTIPLE)
927
/* not a critical problem */
928
char warn_buff[MYSQL_ERRMSG_SIZE];
929
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
931
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
932
ER_TOO_LONG_KEY, warn_buff);
933
/* Align key length to multibyte char boundary */
934
length-= length % sql_field->charset->mbmaxlen;
938
my_error(ER_TOO_LONG_KEY,MYF(0),length);
942
key_part_info->length=(uint16) length;
943
/* Use packed keys for long strings on the first column */
944
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
945
(length >= KEY_DEFAULT_PACK_LENGTH &&
946
(sql_field->sql_type == MYSQL_TYPE_STRING ||
947
sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
948
sql_field->pack_flag & FIELDFLAG_BLOB)))
950
if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB) ||
951
sql_field->sql_type == MYSQL_TYPE_VARCHAR)
952
key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
954
key_info->flags|= HA_PACK_KEY;
956
/* Check if the key segment is partial, set the key flag accordingly */
957
if (length != sql_field->key_length)
958
key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
963
/* Create the key name based on the first column (if not given) */
966
if (key->type == Key::PRIMARY)
970
my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
974
key_name=primary_key_name;
977
else if (!(key_name = key->DOT_STR(name)))
978
key_name=make_unique_key_name(sql_field->field_name,
979
*key_info_buffer, key_info);
980
if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
982
my_error(ER_DUP_KEYNAME, MYF(0), key_name);
985
key_info->name=(char*) key_name;
988
if (!key_info->name || check_column_name(key_info->name))
990
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
993
if (!(key_info->flags & HA_NULL_PART_KEY))
995
key_info->key_length=(uint16) key_length;
996
if (key_length > max_key_length && key->type != Key::FULLTEXT)
998
my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1003
if (!unique_key && !primary_key &&
1004
(file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
1006
my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1009
if (auto_increment > 0)
1011
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1014
/* Sort keys in optimized order */
1015
my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
1016
(qsort_cmp) sort_keys);
1017
create_info->null_bits= null_fields;
1020
it= alter_info->create_list;
1021
while ((sql_field=it++))
1023
Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1025
if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
1027
sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
1028
(sql_field->flags & NOT_NULL_FLAG) &&
1029
(type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1032
An error should be reported if:
1033
- NO_ZERO_DATE SQL mode is active;
1034
- there is no explicit DEFAULT clause (default column value);
1035
- this is a TIMESTAMP column;
1036
- the column is not NULL;
1037
- this is not the DEFAULT CURRENT_TIMESTAMP column.
1039
In other words, an error should be reported if
1040
- NO_ZERO_DATE SQL mode is active;
1041
- the column definition is equivalent to
1042
'column_name TIMESTAMP DEFAULT 0'.
1045
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1053
//////////////////////////////
1054
// mysql_create_table_no_lock() cut and pasted directly from sql_table.cc. (I did make is static after copying it.)
1056
static bool mysql_create_table_no_lock(THD *thd,
1057
const char *db, const char *table_name,
1058
HA_CREATE_INFO *create_info,
1059
Alter_info *alter_info,
1060
bool internal_tmp_table,
1061
uint select_field_count)
1063
char path[FN_REFLEN];
1066
uint db_options, key_count;
1067
KEY *key_info_buffer;
1070
DBUG_ENTER("mysql_create_table_no_lock");
1071
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
1072
db, table_name, internal_tmp_table));
1075
/* Check for duplicate fields and check type of table to create */
1076
if (!alter_info->create_list.elements)
1078
my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1082
if (check_engine(thd, table_name, create_info))
1084
db_options= create_info->table_options;
1085
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1086
db_options|=HA_OPTION_PACK_RECORD;
1087
alias= table_case_name(create_info, table_name);
1089
/* PMC - Done to avoid getting the partition handler by mistake! */
1090
if (!(file= new (thd->mem_root) ha_pbms(pbms_hton, NULL)))
1092
mem_alloc_error(sizeof(handler));
1098
set_table_default_charset(thd, create_info, (char*) db);
1100
if (mysql_prepare_create_table(thd, create_info, alter_info,
1103
&key_info_buffer, &key_count,
1104
select_field_count))
1107
/* Check if table exists */
1108
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1110
path_length= build_tmptable_filename(thd, path, sizeof(path));
1111
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1116
/* check if the table name contains FN_DEVCHAR when defined */
1117
if (strchr(alias, FN_DEVCHAR))
1119
my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
1123
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
1124
internal_tmp_table ? FN_IS_TMP : 0);
1127
/* Check if table already exists */
1128
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1129
find_temporary_table(thd, db, table_name))
1131
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1133
create_info->table_existed= 1; // Mark that table existed
1134
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1135
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1140
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
1144
pthread_mutex_lock(&LOCK_open);
1145
if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1147
if (!access(path,F_OK))
1149
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1151
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
1152
goto unlock_and_end;
1155
We don't assert here, but check the result, because the table could be
1156
in the table definition cache and in the same time the .frm could be
1157
missing from the disk, in case of manual intervention which deletes
1158
the .frm file. The user has to use FLUSH TABLES; to clear the cache.
1159
Then she could create the table. This case is pretty obscure and
1160
therefore we don't introduce a new error message only for it.
1162
if (get_cached_table_share(db, alias))
1164
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
1165
goto unlock_and_end;
1170
Check that table with given name does not already
1171
exist in any storage engine. In such a case it should
1172
be discovered and the error ER_TABLE_EXISTS_ERROR be returned
1173
unless user specified CREATE TABLE IF EXISTS
1174
The LOCK_open mutex has been locked to make sure no
1175
one else is attempting to discover the table. Since
1176
it's not on disk as a frm file, no one could be using it!
1178
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1180
bool create_if_not_exists =
1181
create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1182
int retcode = ha_table_exists_in_engine(thd, db, table_name);
1183
DBUG_PRINT("info", ("exists_in_engine: %"PRIu32"",retcode));
1186
case HA_ERR_NO_SUCH_TABLE:
1187
/* Normal case, no table exists. we can go and create it */
1189
case HA_ERR_TABLE_EXIST:
1190
DBUG_PRINT("info", ("Table existed in handler"));
1192
if (create_if_not_exists)
1194
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
1195
goto unlock_and_end;
1198
DBUG_PRINT("info", ("error: %"PRIu32" from storage engine", retcode));
1199
my_error(retcode, MYF(0),table_name);
1200
goto unlock_and_end;
1204
thd_proc_info(thd, "creating table");
1205
create_info->table_existed= 0; // Mark that table is created
1207
create_info->table_options=db_options;
1209
path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1210
if (rea_create_table(thd, path, db, table_name,
1211
create_info, alter_info->create_list,
1212
key_count, key_info_buffer, file))
1213
goto unlock_and_end;
1215
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1217
/* Open table and put in temporary table list */
1218
#if MYSQL_VERSION_ID > 60005
1219
if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
1221
if (!(open_temporary_table(thd, path, db, table_name, 1)))
1224
#if MYSQL_VERSION_ID > 60005
1225
(void) rm_temporary_table(create_info->db_type, path, false);
1227
(void) rm_temporary_table(create_info->db_type, path);
1229
goto unlock_and_end;
1231
thd->thread_specific_used= TRUE;
1235
Don't write statement if:
1236
- It is an internal temporary table,
1237
- Row-based logging is used and it we are creating a temporary table, or
1238
- The binary log is not open.
1239
Otherwise, the statement shall be binlogged.
1241
if (!internal_tmp_table &&
1242
(!thd->current_stmt_binlog_row_based ||
1243
(thd->current_stmt_binlog_row_based &&
1244
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1245
#if MYSQL_VERSION_ID > 50140
1246
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
1248
write_bin_log(thd, TRUE, thd->query, thd->query_length);
1252
pthread_mutex_unlock(&LOCK_open);
1255
thd_proc_info(thd, "After create");
1261
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1262
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1264
create_info->table_existed= 1; // Mark that table existed
1265
goto unlock_and_end;
1268
////////////////////////////////////////////////////////
1269
////// END OF CUT AND PASTES FROM sql_table.cc ////////
1270
////////////////////////////////////////////////////////
1272
#endif // LOCK_OPEN_HACK_REQUIRED
1275
//------------------------------
1276
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 )
1278
char file_name[FN_REFLEN];
1279
int err = 1, delete_frm = 0;
1280
char field_length_buffer[12], *field_length_ptr;
1281
LEX *save_lex= thd->lex, mylex;
1283
memset(&mylex.create_info, 0, sizeof(HA_CREATE_INFO));
1288
/* setup the create info */
1289
mylex.create_info.db_type = hton;
1290
mylex.create_info.frm_only = 1;
1291
mylex.create_info.default_table_charset = system_charset_info;
1293
/* setup the column info. */
1294
while (info->field_name) {
1295
lex_string_t field_name, comment;
1296
field_name.str = (char*)(info->field_name);
1297
field_name.length = strlen(info->field_name);
1299
comment.str = (char*)(info->comment);
1300
comment.length = strlen(info->comment);
1302
if (info->field_length) {
1303
snprintf(field_length_buffer, 12, "%d", info->field_length);
1304
field_length_ptr = field_length_buffer;
1306
field_length_ptr = NULL;
1308
if (add_field_to_list(thd, &field_name, info->field_type, field_length_ptr, info->field_decimal_length,
1310
#if MYSQL_VERSION_ID > 60005
1312
COLUMN_FORMAT_TYPE_FIXED,
1314
NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/,
1315
NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/))
1324
while (keys->key_name) {
1327
enum Key::Keytype type;
1328
List<Key_part_spec> col_list;
1330
while (keys->key_columns[i]) {
1331
lex.str = (char *)(keys->key_columns[i++]);
1332
lex.length = strlen(lex.str);
1333
col_list.push_back(new Key_part_spec(lex, 0));
1334
//col_list.push_back(new Key_part_spec(keys->key_columns[i++], 0));
1337
switch (keys->key_type) {
1339
type = Key::PRIMARY;
1341
case UNIQUE_KEY_FLAG:
1344
case MULTIPLE_KEY_FLAG:
1345
type = Key::MULTIPLE;
1349
key= new Key(type, keys->key_name, strlen(keys->key_name),
1350
&default_key_create_info,
1352
mylex.alter_info.key_list.push_back(key);
1359
/* Create an internal temp table */
1360
if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0))
1364
/* Read the FRM file. */
1365
build_table_filename(file_name, sizeof(file_name), db, name, "", FN_IS_TMP);
1366
if (readfrm(file_name, frmblob, frmlen))
1373
thd->lex = save_lex;
1376
build_table_filename(file_name, sizeof(file_name), db, name, reg_ext, FN_IS_TMP);
1377
my_delete(file_name, MYF(0));