18
18
#include <drizzled/server_includes.h>
19
19
#include <storage/myisam/myisam.h>
20
#include <drizzled/sql_show.h>
20
#include <drizzled/show.h>
21
21
#include <drizzled/error.h>
22
22
#include <drizzled/gettext.h>
23
23
#include <drizzled/data_home.h>
24
24
#include <drizzled/sql_parse.h>
25
#include <mysys/hash.h>
26
#include <drizzled/sql_lex.h>
27
#include <drizzled/session.h>
28
#include <drizzled/sql_base.h>
29
#include <drizzled/db.h>
30
#include <drizzled/lock.h>
31
#include <drizzled/unireg.h>
32
#include <drizzled/item/int.h>
33
#include <drizzled/item/empty_string.h>
34
#include <drizzled/replicator.h>
38
extern HASH lock_db_cache;
26
40
int creating_table= 0; // How many mysql_create_table are running
28
const char * primary_key_name="PRIMARY";
43
bool is_primary_key(KEY *key_info)
45
static const char * primary_key_name="PRIMARY";
46
return (strcmp(key_info->name, primary_key_name)==0);
49
const char* is_primary_key_name(const char* key_name)
51
static const char * primary_key_name="PRIMARY";
52
if (strcmp(key_name, primary_key_name)==0)
30
58
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
31
59
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
108
154
if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
109
155
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
110
return((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
112
(from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
156
return((uint32_t) (strncpy(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
158
(from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
113
159
length= strconvert(system_charset_info, from,
114
160
&my_charset_filename, to, to_length, &errors);
115
161
if (check_if_legal_tablename(to) &&
152
198
build_tmptable_filename() for them.
201
path length on success, 0 on failure
158
204
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
159
205
const char *table_name, const char *ext, uint32_t flags)
161
208
char dbbuff[FN_REFLEN];
162
209
char tbbuff[FN_REFLEN];
210
int rootdir_len= strlen(FN_ROOTDIR);
164
212
if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
165
my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
213
strncpy(tbbuff, table_name, sizeof(tbbuff));
167
215
tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
169
217
tablename_to_filename(db, dbbuff, sizeof(dbbuff));
218
table_path= drizzle_data_home;
219
int without_rootdir= table_path.length()-rootdir_len;
171
char *end = buff + bufflen;
172
221
/* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
173
char *pos = my_stpncpy(buff, drizzle_data_home, bufflen);
174
int rootdir_len= strlen(FN_ROOTDIR);
175
if (pos - rootdir_len >= buff &&
176
memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
177
pos= my_stpncpy(pos, FN_ROOTDIR, end - pos);
178
pos= my_stpncpy(pos, dbbuff, end-pos);
179
pos= my_stpncpy(pos, FN_ROOTDIR, end-pos);
222
if (without_rootdir >= 0)
224
char *tmp= (char*)table_path.c_str()+without_rootdir;
225
if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
226
table_path.append(FN_ROOTDIR);
229
table_path.append(dbbuff);
230
table_path.append(FN_ROOTDIR);
180
231
#ifdef USE_SYMDIR
181
unpack_dirname(buff, buff);
184
pos= my_stpncpy(pos, tbbuff, end - pos);
185
pos= my_stpncpy(pos, ext, end - pos);
234
table_path.append(tbbuff);
235
table_path.append(ext);
237
if (bufflen < table_path.length())
240
strcpy(buff, table_path.c_str());
241
return table_path.length();
192
Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
246
Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
195
249
build_tmptable_filename()
196
session The thread handle.
250
session The thread handle.
197
251
buff Where to write result in my_charset_filename.
198
252
bufflen buff size
202
256
Uses current_pid, thread_id, and tmp_table counter to create
203
a file name in mysql_tmpdir.
257
a file name in drizzle_tmpdir.
260
path length on success, 0 on failure
209
263
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
266
ostringstream path_str, post_tmpdir_str;
212
char *p= my_stpncpy(buff, mysql_tmpdir, bufflen);
213
snprintf(p, bufflen - (p - buff), "/%s%lx_%"PRIx64"_%x%s",
214
tmp_file_prefix, current_pid,
215
session->thread_id, session->tmp_table++, reg_ext);
269
path_str << drizzle_tmpdir;
270
post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
271
post_tmpdir_str << session->thread_id << session->tmp_table++ << reg_ext;
272
tmp= post_tmpdir_str.str();
217
274
if (lower_case_table_names)
219
/* Convert all except tmpdir to lower case */
220
my_casedn_str(files_charset_info, p);
223
uint32_t length= unpack_filename(buff, buff);
275
transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
279
if (bufflen < path_str.str().length())
282
length= unpack_filename(buff, path_str.str().c_str());
481
if (table_type == NULL)
483
mysql_frm_type(session, path, &frm_db_type);
484
table_type= ha_resolve_by_legacy_type(session, frm_db_type);
486
532
// Remove extension for delete
487
533
*(end= path + path_length - reg_ext_length)= '\0';
488
error= ha_delete_table(session, table_type, path, db, table->table_name,
534
error= ha_delete_table(session, path, db, table->table_name,
489
535
!dont_log_query);
490
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
491
(if_exists || table_type == NULL))
536
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
494
540
session->clear_error();
797
851
FIELDFLAG_INTERVAL;
798
852
if (sql_field->charset->state & MY_CS_BINSORT)
799
853
sql_field->pack_flag|=FIELDFLAG_BINARY;
800
sql_field->unireg_check=Field::INTERVAL_FIELD;
801
854
if (check_duplicates_in_interval("ENUM",sql_field->field_name,
802
855
sql_field->interval,
803
856
sql_field->charset, &dup_val_count))
806
case DRIZZLE_TYPE_NEWDATE: // Rest of string types
859
case DRIZZLE_TYPE_DATE: // Rest of string types
807
860
case DRIZZLE_TYPE_TIME:
808
861
case DRIZZLE_TYPE_DATETIME:
809
862
case DRIZZLE_TYPE_NULL:
810
sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
863
sql_field->pack_flag=f_settype((uint32_t) sql_field->sql_type);
812
865
case DRIZZLE_TYPE_NEWDECIMAL:
813
866
sql_field->pack_flag=(FIELDFLAG_NUMBER |
925
978
save_cs= sql_field->charset;
926
979
if ((sql_field->flags & BINCMP_FLAG) &&
927
!(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
928
MY_CS_BINSORT,MYF(0))))
980
!(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, MY_CS_BINSORT)))
931
strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
932
STRING_WITH_LEN("_bin"));
984
strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
985
tmp_pos+= strlen(tmp);
986
strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
933
987
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
1604
Set table default charset, if not set
1607
set_table_default_charset()
1608
create_info Table create information
1611
If the table character set was not given explicitely,
1612
let's fetch the database default character set and
1613
apply it to the table.
1616
static void set_table_default_charset(Session *session,
1617
HA_CREATE_INFO *create_info, char *db)
1620
If the table character set was not given explicitly,
1621
let's fetch the database default character set and
1622
apply it to the table.
1624
if (!create_info->default_table_charset)
1626
HA_CREATE_INFO db_info;
1628
load_db_opt_by_name(session, db, &db_info);
1630
create_info->default_table_charset= db_info.default_table_charset;
1636
1658
Extend long VARCHAR fields to blob & prepare field if it's a blob
2087
2110
if (lower_case_table_names == 2 && file &&
2088
2111
!(file->ha_table_flags() & HA_FILE_BASED))
2090
my_stpcpy(tmp_name, old_name);
2113
strcpy(tmp_name, old_name);
2091
2114
my_casedn_str(files_charset_info, tmp_name);
2092
2115
build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2093
2116
flags & FN_FROM_IS_TMP);
2094
2117
from_base= lc_from;
2096
my_stpcpy(tmp_name, new_name);
2119
strcpy(tmp_name, new_name);
2097
2120
my_casedn_str(files_charset_info, tmp_name);
2098
2121
build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2099
2122
flags & FN_TO_IS_TMP);
2267
2299
Check if this is a table type that stores index and data separately,
2268
2300
like ISAM or MyISAM. We assume fixed order of engine file name
2269
2301
extentions array. First element of engine file name extentions array
2270
is meta/index file extention. Second element - data file extention.
2302
is meta/index file extention. Second element - data file extention.
2272
2304
ext= table->file->bas_ext();
2273
2305
if (!ext[0] || !ext[1])
2274
2306
goto end; // No data file
2276
2308
// Name of data file
2277
strxmov(from, table->s->normalized_path.str, ext[1], NULL);
2309
sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2278
2310
if (stat(from, &stat_info))
2279
2311
goto end; // Can't use USE_FRM flag
2281
2313
snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
2282
from, current_pid, session->thread_id);
2314
from, (unsigned long)current_pid, session->thread_id);
2284
2316
/* If we could open the table, close it */
2285
2317
if (table_list->table)
2759
2768
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2761
2770
return(mysql_admin_table(session, tables, check_opt,
2762
"repair", TL_WRITE, 1,
2763
test(check_opt->sql_flags & TT_USEFRM),
2765
&prepare_for_repair,
2766
&handler::ha_repair));
2771
"repair", TL_WRITE, 1,
2774
&prepare_for_repair,
2775
&handler::ha_repair));
2770
2779
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2772
2781
return(mysql_admin_table(session, tables, check_opt,
2773
"optimize", TL_WRITE, 1,0,0,0,
2774
&handler::ha_optimize));
2782
"optimize", TL_WRITE, 1,0,0,0,
2783
&handler::ha_optimize));
2876
2885
schema_table->table->use_all_columns();
2877
2886
if (mysql_prepare_alter_table(session, schema_table->table,
2878
2887
&local_create_info, &alter_info))
2880
2890
if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2881
2891
tmp_table, &db_options,
2882
2892
schema_table->table->file,
2883
2893
&schema_table->table->s->key_info, &keys, 0))
2885
2896
local_create_info.max_rows= 0;
2886
if (mysql_create_frm(session, dst_path, NULL, NULL,
2897
if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
2887
2898
&local_create_info, alter_info.create_list,
2888
2899
keys, schema_table->table->s->key_info,
2889
schema_table->table->file))
2900
schema_table->table->file, true))
2896
2907
Create a table identical to the specified table
2981
else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
2983
if (my_errno == ENOENT)
2984
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2986
my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2987
pthread_mutex_unlock(&LOCK_open);
2994
int frmcopyr= my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE));
2996
string dfesrc(src_path);
2997
string dfedst(dst_path);
2999
dfesrc.replace(dfesrc.find(".frm"), 4, ".dfe" );
3000
dfedst.replace(dfedst.find(".frm"), 4, ".dfe" );
3002
int dfecopyr= my_copy(dfesrc.c_str(), dfedst.c_str(),
3003
MYF(MY_DONT_OVERWRITE_FILE));
3005
if(frmcopyr || dfecopyr) // FIXME: should handle only one fail.
3007
if (my_errno == ENOENT)
3008
my_error(ER_BAD_DB_ERROR,MYF(0),db);
3010
my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
3011
pthread_mutex_unlock(&LOCK_open);
3754
3763
char path[FN_REFLEN];
3756
3765
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
3757
tmp_file_prefix, current_pid, session->thread_id);
3766
TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3758
3767
/* Safety fix for InnoDB */
3759
3768
if (lower_case_table_names)
3760
3769
my_casedn_str(files_charset_info, tmp_name);
3761
3770
altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
3762
altered_create_info.frm_only= 1;
3763
3772
if ((error= create_temporary_table(session, table, new_db, tmp_name,
3764
3773
&altered_create_info,
3765
3774
alter_info, db_change)))
4097
4104
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
4101
4108
Check that the DATE/DATETIME not null field we are going to add is
4102
4109
either has a default value or the '0000-00-00' is allowed by the
4104
4111
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4105
4112
flag to allow ALTER Table only if the table to be altered is empty.
4107
if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
4114
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4108
4115
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4109
!alter_info->datetime_field &&
4110
!(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4111
session->variables.sql_mode & MODE_NO_ZERO_DATE)
4116
!alter_info->datetime_field &&
4117
!(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4118
session->variables.sql_mode & MODE_NO_ZERO_DATE)
4113
alter_info->datetime_field= def;
4114
alter_info->error_if_not_empty= true;
4120
alter_info->datetime_field= def;
4121
alter_info->error_if_not_empty= true;
4116
4123
if (!def->after)
4117
4124
new_create_list.push_back(def);
4155
4162
my_error(ER_BAD_FIELD_ERROR, MYF(0),
4156
4163
alter_info->alter_list.head()->name, table->s->table_name.str);
4159
4166
if (!new_create_list.elements)
4161
4168
my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS),
4167
4174
Collect all keys which isn't in drop list. Add only those
4168
4175
for which some fields exists.
4171
4178
for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
4173
4180
char *key_name= key_info->name;
4174
4181
Alter_drop *drop;
4175
4182
drop_it.rewind();
4176
4183
while ((drop=drop_it++))
4178
4185
if (drop->type == Alter_drop::KEY &&
4179
4186
!my_strcasecmp(system_charset_info,key_name, drop->name))
4184
4191
drop_it.remove();
4377
4383
uint32_t order_num, order_st *order, bool ignore)
4379
4385
Table *table, *new_table=0, *name_lock= 0;;
4386
string new_name_str;
4381
4388
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4382
4389
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4383
4390
char path[FN_REFLEN];
4384
4391
ha_rows copied= 0,deleted= 0;
4385
4392
handlerton *old_db_type, *new_db_type, *save_old_db_type;
4386
legacy_db_type table_type;
4394
new_name_buff[0]= '\0';
4388
4396
if (table_list && table_list->schema_table)
4390
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
4398
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4411
4419
/* Conditionally writes to binlog. */
4412
4420
return(mysql_discard_or_import_tablespace(session,table_list,
4413
4421
alter_info->tablespace_op));
4414
char* pos= new_name_buff;
4415
char* pos_end= pos+strlen(new_name_buff)-1;
4416
pos= my_stpncpy(new_name_buff, drizzle_data_home, pos_end-pos);
4417
pos= my_stpncpy(new_name_buff, "/", pos_end-pos);
4418
pos= my_stpncpy(new_name_buff, db, pos_end-pos);
4419
pos= my_stpncpy(new_name_buff, "/", pos_end-pos);
4420
pos= my_stpncpy(new_name_buff, table_name, pos_end-pos);
4421
pos= my_stpncpy(new_name_buff, reg_ext, pos_end-pos);
4423
oss << drizzle_data_home << "/" << db << "/" << table_name << reg_ext;
4423
(void) unpack_filename(new_name_buff, new_name_buff);
4425
(void) unpack_filename(new_name_buff, oss.str().c_str());
4425
4427
If this is just a rename of a view, short cut to the
4426
4428
following scenario: 1) lock LOCK_open 2) do a RENAME
4443
4444
/* Check that we are not trying to rename to an existing table */
4446
my_stpcpy(new_name_buff,new_name);
4447
my_stpcpy(new_alias= new_alias_buff, new_name);
4447
strcpy(new_name_buff,new_name);
4448
strcpy(new_alias= new_alias_buff, new_name);
4448
4449
if (lower_case_table_names)
4450
4451
if (lower_case_table_names != 2)
4452
my_casedn_str(files_charset_info, new_name_buff);
4453
new_alias= new_name; // Create lower case table name
4453
my_casedn_str(files_charset_info, new_name_buff);
4454
new_alias= new_name; // Create lower case table name
4455
4456
my_casedn_str(files_charset_info, new_name);
4792
4792
close_temporary_table(session, altered_table, 1, 1);
4795
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, tmp_file_prefix,
4796
current_pid, session->thread_id);
4795
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
4796
(unsigned long)current_pid, session->thread_id);
4797
4797
/* Safety fix for innodb */
4798
4798
if (lower_case_table_names)
4799
4799
my_casedn_str(files_charset_info, tmp_name);
4802
4802
/* Create a temporary table with the new format */
4803
if ((error= create_temporary_table(session, table, new_db, tmp_name,
4804
create_info, alter_info,
4803
if ((error= create_temporary_table(session, table, new_db, tmp_name,
4804
create_info, alter_info,
4805
4805
!strcmp(db, new_db))))
4822
char path[FN_REFLEN];
4822
char tmp_path[FN_REFLEN];
4823
4823
/* table is a normal table: Create temporary table in same directory */
4824
build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4824
build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, "",
4826
4826
/* Open our intermediate table */
4827
new_table=open_temporary_table(session, path, new_db, tmp_name, 0, OTM_OPEN);
4827
new_table=open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
4829
4829
if (!new_table)
4978
4979
session->set_proc_info("end");
4980
assert(!(mysql_bin_log.is_open() &&
4981
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4982
4981
write_bin_log(session, true, session->query, session->query_length);
4984
if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
4983
if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
4987
4986
For the alter table to be properly flushed to the logs, we
4988
4987
have to open the new table. If not, we get a problem on server
4989
4988
shutdown. But we do not need to attach MERGE children.
4991
char path[FN_REFLEN];
4990
char table_path[FN_REFLEN];
4992
4991
Table *t_table;
4993
build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
4994
t_table= open_temporary_table(session, path, new_db, tmp_name, false, OTM_OPEN);
4992
build_table_filename(table_path, sizeof(table_path), new_db, table_name, "", 0);
4993
t_table= open_temporary_table(session, table_path, new_db, tmp_name, false, OTM_OPEN);
4997
4996
intern_close_table(t_table);
5001
sql_print_warning(_("Could not open table %s.%s after rename\n"),
5000
errmsg_printf(ERRMSG_LVL_WARN,
5001
_("Could not open table %s.%s after rename\n"),
5003
5003
ha_flush_logs(old_db_type);
5005
5005
table_list->table=0; // For query cache
5022
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5023
(ulong) (copied + deleted), (ulong) deleted,
5024
(ulong) session->cuted_fields);
5025
my_ok(session, copied + deleted, 0L, tmp_name);
5026
session->some_tables_deleted=0;
5023
* Field::store() may have called my_error(). If this is
5024
* the case, we must not send an ok packet, since
5025
* Diagnostics_area::is_set() will fail an assert.
5027
if (! session->is_error())
5029
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5030
(ulong) (copied + deleted), (ulong) deleted,
5031
(ulong) session->cuted_fields);
5032
session->my_ok(copied + deleted, 0L, tmp_name);
5033
session->some_tables_deleted=0;
5038
/* my_error() was called. Return true (which means error...) */