summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2001-01-28 21:35:50 +0200
committerunknown <monty@donna.mysql.com>2001-01-28 21:35:50 +0200
commit184e24b2253a81b03476e3d4d8cf56d5eb9dbf18 (patch)
treefabb5447e17b9f0959cb83b6d88351367ca53645 /sql
parent298ba0d39d6d38d5be860a3ad8a55b469b67e7d8 (diff)
downloadmariadb-git-184e24b2253a81b03476e3d4d8cf56d5eb9dbf18.tar.gz
Fixed ALTER TABLE on MERGE tables
Fixed bug in DISTINCT Docs/manual.texi: Updated Changelog Cleaned up adding character sets merge/open.c: skip comments myisam/mi_check.c: Fixed bug when sorting index on Windows myisammrg/myrg_info.c: Use only portable printf arguments myisammrg/myrg_rrnd.c: Use only portable printf arguments mysql-test/r/distinct.result: Added test case for bug in distinct mysql-test/r/merge.result: Added test for ALTER TABLE mysql-test/t/distinct.test: Added test case for bug in distinct mysql-test/t/merge.test: Added test for ALTER TABLE sql-bench/crash-me.sh: Fixed portability issues sql/ha_myisammrg.cc: Fixed for ALTER TABLE on MERGE tables sql/item_sum.cc: Fixed bug in DISTINCT sql/sql_db.cc: Added test of namelen in check_db_name sql/sql_select.cc: Fixed bug in DISTINCT sql/sql_select.h: Fixed bug in DISTINCT sql/sql_table.cc: Fixed ALTER TABLE on MERGE tables sql/table.cc: Added test of namelen in check_db_name sql/table.h: Fixed ALTER TABLE on MERGE tables
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_myisammrg.cc1
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/sql_db.cc4
-rw-r--r--sql/sql_select.cc97
-rw-r--r--sql/sql_select.h8
-rw-r--r--sql/sql_table.cc9
-rw-r--r--sql/table.cc3
-rw-r--r--sql/table.h1
8 files changed, 92 insertions, 33 deletions
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 863054b4837..4c562282090 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -177,6 +177,7 @@ void ha_myisammrg::info(uint flag)
errkey = info.errkey;
table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1;
table->db_options_in_use = info.options;
+ table->is_view=1;
mean_rec_length=info.reclength;
block_size=0;
update_time=0;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 1c236e19bda..375ba081f80 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -811,7 +811,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
for (uint i=0; i < arg_count ; i++)
if (list.push_back(args[i]))
return 1;
- count_field_types(tmp_table_param,list);
+ count_field_types(tmp_table_param,list,0);
if (table)
{
free_tmp_table(thd, table);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 89e7faa237c..25bbe75e944 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -35,7 +35,7 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
long result=1;
DBUG_ENTER("mysql_create_db");
- if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db))
+ if (!stripp_sp(db) || check_db_name(db))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, db);
DBUG_VOID_RETURN;
@@ -103,7 +103,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
MY_DIR *dirp;
DBUG_ENTER("mysql_rm_db");
- if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db))
+ if (!stripp_sp(db) || check_db_name(db))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, db);
DBUG_VOID_RETURN;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2d8373ec067..526c78e0856 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -268,7 +268,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
join.first_record=join.sort_and_group=0;
join.select_options=select_options;
join.result=result;
- count_field_types(&join.tmp_table_param,all_fields);
+ count_field_types(&join.tmp_table_param,all_fields,0);
join.const_tables=0;
join.having=0;
join.group= group != 0;
@@ -632,9 +632,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
/*
** If we have different sort & group then we must sort the data by group
** and copy it to another tmp table
+ ** This code is also used if we are using distinct something
+ ** we haven't been able to store in the temporary table yet
+ ** like SEC_TO_TIME(SUM(...)).
*/
- if (group && (!test_if_subpart(group,order) || select_distinct))
+ if (group && (!test_if_subpart(group,order) || select_distinct) ||
+ (select_distinct &&
+ join.tmp_table_param.using_indirect_summary_function))
{ /* Must copy to another table */
TABLE *tmp_table2;
DBUG_PRINT("info",("Creating group table"));
@@ -644,11 +649,16 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (make_simple_join(&join,tmp_table))
goto err;
calc_group_buffer(&join,group);
- count_field_types(&join.tmp_table_param,all_fields);
+ count_field_types(&join.tmp_table_param,all_fields,
+ select_distinct && !group);
+ join.tmp_table_param.hidden_field_count=(all_fields.elements-
+ fields.elements);
/* group data to new table */
if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields,
- (ORDER*) 0, 0 , 1, 0,
+ (ORDER*) 0,
+ select_distinct && !group,
+ 1, 0,
join.select_options)))
goto err; /* purecov: inspected */
if (group)
@@ -657,7 +667,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (create_sort_index(join.join_tab,group,HA_POS_ERROR) ||
alloc_group_fields(&join,group))
{
- free_tmp_table(thd,tmp_table2); /* purecov: inspected */
+ free_tmp_table(thd,tmp_table2); /* purecov: inspected */
goto err; /* purecov: inspected */
}
group=0;
@@ -696,14 +706,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (make_simple_join(&join,tmp_table))
goto err;
calc_group_buffer(&join,group);
- count_field_types(&join.tmp_table_param,all_fields);
+ count_field_types(&join.tmp_table_param,all_fields,0);
}
if (procedure)
{
if (procedure->change_columns(fields) ||
result->prepare(fields))
goto err;
- count_field_types(&join.tmp_table_param,all_fields);
+ count_field_types(&join.tmp_table_param,all_fields,0);
}
if (join.group || join.tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP)))
@@ -3265,6 +3275,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{
TABLE *table;
uint i,field_count,reclength,null_count,null_pack_length,
+ hidden_null_count, hidden_null_pack_length, hidden_field_count,
blob_count,group_null_items;
bool using_unique_constraint=0;
char *tmpname,path[FN_REFLEN];
@@ -3292,9 +3303,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(*tmp->item)->marker=4; // Store null in key
if (param->group_length >= MAX_BLOB_WIDTH)
using_unique_constraint=1;
+ if (group)
+ distinct=0; // Can't use distinct
}
field_count=param->field_count+param->func_count+param->sum_func_count;
+ hidden_field_count=param->hidden_field_count;
if (!my_multi_malloc(MYF(MY_WME),
&table,sizeof(*table),
&reg_field,sizeof(Field*)*(field_count+1),
@@ -3334,9 +3348,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->tmp_table=1;
table->db_low_byte_first=1; // True for HEAP and MyISAM
- /* Calculate with type of fields we will need in heap table */
+ /* Calculate which type of fields we will store in the temporary table */
- reclength=blob_count=null_count=group_null_items=0;
+ reclength=blob_count=null_count=hidden_null_count=group_null_items=0;
+ param->using_indirect_summary_function=0;
List_iterator<Item> li(fields);
Item *item;
@@ -3344,8 +3359,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
while ((item=li++))
{
Item::Type type=item->type();
- if (item->with_sum_func && type != Item::SUM_FUNC_ITEM ||
- item->const_item())
+ if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
+ {
+ /*
+ Mark that the we have ignored an item that refers to a summary
+ function. We need to know this if someone is going to use
+ DISTINCT on the result.
+ */
+ param->using_indirect_summary_function=1;
+ continue;
+ }
+ if (item->const_item()) // We don't have to store this
continue;
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
{ /* Can't calc group yet */
@@ -3396,6 +3420,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
*(reg_field++) =new_field;
}
+ if (!--hidden_field_count)
+ hidden_null_count=null_count;
}
field_count= (uint) (reg_field - table->field);
@@ -3420,8 +3446,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->blob_fields=blob_count;
if (blob_count == 0)
- null_count++; // For delete link
- reclength+=(null_pack_length=(null_count+7)/8);
+ {
+ /* We need to ensure that first byte is not 0 for the delete link */
+ if (hidden_null_count)
+ hidden_null_count++;
+ else
+ null_count++;
+ }
+ hidden_null_pack_length=(hidden_null_count+7)/8;
+ null_pack_length=hidden_null_count+(null_count+7)/8;
+ reclength+=null_pack_length;
if (!reclength)
reclength=1; // Dummy select
@@ -3449,6 +3483,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bfill(null_flags,null_pack_length,255); // Set null fields
}
null_count= (blob_count == 0) ? 1 : 0;
+ hidden_field_count=param->hidden_field_count;
for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
{
Field *field= *reg_field;
@@ -3496,6 +3531,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
recinfo->type=FIELD_SKIPP_ENDSPACE;
else
recinfo->type=FIELD_NORMAL;
+ if (!--hidden_field_count)
+ null_count=(null_count+7) & ~7; // move to next byte
}
param->copy_field_count=(uint) (copy - param->copy_field);
@@ -3559,11 +3596,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
}
- if (distinct && !group)
+ if (distinct)
{
- /* Create an unique key or an unique constraint over all columns */
- keyinfo->key_parts=field_count+ test(null_count);
- if (distinct && allow_distinct_limit)
+ /*
+ Create an unique key or an unique constraint over all columns
+ that should be in the result. In the temporary table, there are
+ 'param->hidden_field_count' extra columns, whose null bits are stored
+ in the first 'hidden_null_pack_length' bytes of the row.
+ */
+ null_pack_length-=hidden_null_pack_length;
+ keyinfo->key_parts=field_count+ test(null_pack_length);
+ if (allow_distinct_limit)
{
set_if_smaller(table->max_rows,thd->select_limit);
param->end_write_records=thd->select_limit;
@@ -3585,11 +3628,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->flags=HA_NOSAME;
keyinfo->key_length=(uint16) reclength;
keyinfo->name=(char*) "tmp";
- if (null_count)
+ if (null_pack_length)
{
key_part_info->null_bit=0;
- key_part_info->offset=0;
- key_part_info->length=(null_count+7)/8;
+ key_part_info->offset=hidden_null_pack_length;
+ key_part_info->length=null_pack_length;
key_part_info->field=new Field_string((char*) table->record[0],
(uint32) key_part_info->length,
(uchar*) 0,
@@ -3600,7 +3643,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->type= HA_KEYTYPE_BINARY;
key_part_info++;
}
- for (i=0,reg_field=table->field; i < field_count;
+ for (i=param->hidden_field_count, reg_field=table->field + i ;
+ i < field_count;
i++, reg_field++, key_part_info++)
{
key_part_info->null_bit=0;
@@ -5917,13 +5961,14 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
*****************************************************************************/
void
-count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields)
+count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
+ bool reset_with_sum_func)
{
List_iterator<Item> li(fields);
Item *field;
- param->field_count=param->sum_func_count=
- param->func_count=0;
+ param->field_count=param->sum_func_count=param->func_count=
+ param->hidden_field_count=0;
param->quick_group=1;
while ((field=li++))
{
@@ -5949,7 +5994,11 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields)
}
}
else
+ {
param->func_count++;
+ if (reset_with_sum_func)
+ field->with_sum_func=0;
+ }
}
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 8ac00dde4c5..2f7454e4059 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -124,10 +124,13 @@ class TMP_TABLE_PARAM {
KEY *keyinfo;
ha_rows end_write_records;
uint copy_field_count,field_count,sum_func_count,func_count;
+ uint hidden_field_count;
uint group_parts,group_length;
uint quick_group;
+ bool using_indirect_summary_function;
- TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) {}
+ TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0)
+ {}
~TMP_TABLE_PARAM()
{
cleanup();
@@ -178,7 +181,8 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
bool allow_distinct_limit, uint select_options);
void free_tmp_table(THD *thd, TABLE *entry);
-void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields);
+void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
+ bool reset_with_sum_func);
bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item_result_field **func_ptr);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 954a1f8efd7..9e720558456 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1443,10 +1443,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->cuted_fields=0L;
thd->proc_info="copy to tmp table";
next_insert_id=thd->next_insert_id; // Remember for loggin
- error=copy_data_between_tables(table,new_table,create_list,handle_duplicates,
- order, &copied,&deleted);
+ copied=deleted=0;
+ if (!new_table->is_view)
+ error=copy_data_between_tables(table,new_table,create_list,
+ handle_duplicates,
+ order, &copied, &deleted);
thd->last_insert_id=next_insert_id; // Needed for correct log
- thd->count_cuted_fields=0; /* Don`t calc cuted fields */
+ thd->count_cuted_fields=0; // Don`t calc cuted fields
new_table->time_stamp=save_time_stamp;
if (table->tmp_table)
diff --git a/sql/table.cc b/sql/table.cc
index 762c28b0fbf..8ee6ee02d68 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1033,6 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr)
bool check_db_name(const char *name)
{
+ const char *start=end;
while (*name)
{
#if defined(USE_MB) && defined(USE_MB_IDENT)
@@ -1050,7 +1051,7 @@ bool check_db_name(const char *name)
return 1;
name++;
}
- return 0;
+ return (uint) (name - start) > NAME_LEN;
}
diff --git a/sql/table.h b/sql/table.h
index 8121271b479..c17a1eca830 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -93,6 +93,7 @@ struct st_table {
my_bool locked_by_flush;
my_bool locked_by_name;
my_bool crashed;
+ my_bool is_view;
Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */
*rowid_field;