summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <igor@olga.mysql.com>2007-06-30 20:49:28 -0700
committerunknown <igor@olga.mysql.com>2007-06-30 20:49:28 -0700
commit26a2b00498c5da514abe7056032ea37f7115b1e1 (patch)
treeed6bbc6971d75074b67617c9c71dbae1f71a8996 /sql
parent2ca2b232e3fd7e82c4502f4ebd21a85e01d547a3 (diff)
parent8dcd5fca6977a8aafb0dd874b348e0078eafda94 (diff)
downloadmariadb-git-26a2b00498c5da514abe7056032ea37f7115b1e1.tar.gz
Merge olga.mysql.com:/home/igor/mysql-5.0-opt
into olga.mysql.com:/home/igor/dev-opt/mysql-5.1-opt mysql-test/r/binary.result: Auto merged mysql-test/r/ctype_collate.result: Auto merged mysql-test/r/ctype_utf8.result: Auto merged mysql-test/t/binary.test: Auto merged mysql-test/t/create.test: Auto merged mysql-test/t/ctype_utf8.test: Auto merged sql/field_conv.cc: Auto merged sql/item.cc: Auto merged sql/item_subselect.cc: Auto merged sql/item_sum.cc: Auto merged sql/item_sum.h: Auto merged sql/sql_class.h: Auto merged sql/sql_insert.cc: Auto merged sql/sql_select.cc: Auto merged sql-common/client.c: Auto merged sql/sql_select.h: Auto merged sql/table.cc: Auto merged storage/myisam/mi_open.c: Auto merged strings/ctype-simple.c: Auto merged mysql-test/r/create.result: Manual merge. mysql-test/r/subselect.result: Manual merge. mysql-test/r/type_enum.result: Manual merge. mysql-test/t/type_enum.test: Manual merge. mysql-test/include/mix1.inc: Manual merge. mysql-test/r/innodb_mysql.result: Manual merge. mysql-test/t/subselect.test: Manual merge. sql/sql_parse.cc: Manual merge. storage/myisam/mi_key.c: Manual merge.
Diffstat (limited to 'sql')
-rw-r--r--sql/field_conv.cc17
-rw-r--r--sql/item.cc12
-rw-r--r--sql/item_subselect.cc3
-rw-r--r--sql/item_sum.cc4
-rw-r--r--sql/item_sum.h9
-rw-r--r--sql/sql_parse.cc9
-rw-r--r--sql/sql_select.cc49
-rw-r--r--sql/sql_select.h4
-rw-r--r--sql/table.cc14
9 files changed, 91 insertions, 30 deletions
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 63810c8b113..44aea9acee0 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -307,6 +307,15 @@ static void do_field_string(Copy_field *copy)
}
+static void do_field_enum(Copy_field *copy)
+{
+ if (copy->from_field->val_int() == 0)
+ ((Field_enum *) copy->to_field)->store_type((ulonglong) 0);
+ else
+ do_field_string(copy);
+}
+
+
static void do_field_varbinary_pre50(Copy_field *copy)
{
char buff[MAX_FIELD_WIDTH];
@@ -667,7 +676,13 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
to->real_type() == MYSQL_TYPE_SET)
{
if (!to->eq_def(from))
- return do_field_string;
+ {
+ if (from->real_type() == MYSQL_TYPE_ENUM &&
+ to->real_type() == MYSQL_TYPE_ENUM)
+ return do_field_enum;
+ else
+ return do_field_string;
+ }
}
else if (to->charset() != from->charset())
return do_field_string;
diff --git a/sql/item.cc b/sql/item.cc
index 4fa6a2a8517..d7743c491eb 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -6687,9 +6687,15 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
expansion of the size of the values because of character set
conversions.
*/
- max_length= max(old_max_chars * collation.collation->mbmaxlen,
- display_length(item) / item->collation.collation->mbmaxlen *
- collation.collation->mbmaxlen);
+ if (collation.collation != &my_charset_bin)
+ {
+ max_length= max(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+ }
+ else
+ set_if_bigger(max_length, display_length(item));
break;
}
case REAL_RESULT:
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 000abb313a0..1d042860d73 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -985,7 +985,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
DBUG_RETURN(RES_ERROR);
thd->lex->allow_sum_func= save_allow_sum_func;
/* we added aggregate function => we have to change statistic */
- count_field_types(&join->tmp_table_param, join->all_fields, 0);
+ count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
+ 0);
subs= new Item_singlerow_subselect(select_lex);
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 10bd24dbb66..e2d4c02d986 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2480,7 +2480,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
}
if (always_null)
return FALSE;
- count_field_types(tmp_table_param,list,0);
+ count_field_types(select_lex, tmp_table_param, list, 0);
tmp_table_param->force_copy_fields= force_copy_fields;
DBUG_ASSERT(table == 0);
if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
@@ -3286,7 +3286,7 @@ bool Item_func_group_concat::setup(THD *thd)
setup_order(thd, args, context->table_list, list, all_fields, *order))
DBUG_RETURN(TRUE);
- count_field_types(tmp_table_param,all_fields,0);
+ count_field_types(select_lex, tmp_table_param, all_fields, 0);
tmp_table_param->force_copy_fields= force_copy_fields;
DBUG_ASSERT(table == 0);
/*
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 84b425755d1..b3a382012f1 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -966,8 +966,15 @@ public:
bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
+
+ if (init_sum_func_check(thd))
+ return TRUE;
+
fixed= 1;
- return udf.fix_fields(thd, this, this->arg_count, this->args);
+ if (udf.fix_fields(thd, this, this->arg_count, this->args))
+ return TRUE;
+
+ return check_sum_func(thd, ref);
}
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
virtual bool have_field_update(void) const { return 0; }
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a8dbebe012d..bf07bae379d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3012,6 +3012,7 @@ end_with_restore_list:
break;
case SQLCOM_LOCK_TABLES:
unlock_locked_tables(thd);
+ /* we must end the trasaction first, regardless of anything */
if (end_active_trans(thd))
goto error;
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0))
@@ -3030,7 +3031,15 @@ end_with_restore_list:
send_ok(thd);
}
else
+ {
+ /*
+ Need to end the current transaction, so the storage engine (InnoDB)
+ can free its locks if LOCK TABLES locked some tables before finding
+ that it can't lock a table in its list
+ */
+ end_active_trans(thd);
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
+ }
thd->in_lock_tables=0;
break;
case SQLCOM_CREATE_DB:
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 504046ef43f..3cda4029161 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -606,7 +606,7 @@ JOIN::prepare(Item ***rref_pointer_array,
goto err; /* purecov: inspected */
/* Init join struct */
- count_field_types(&tmp_table_param, all_fields, 0);
+ count_field_types(select_lex, &tmp_table_param, all_fields, 0);
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
this->group= group_list != 0;
unit= unit_arg;
@@ -1781,7 +1781,7 @@ JOIN::exec()
if (make_simple_join(curr_join, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, group_list);
- count_field_types(&curr_join->tmp_table_param,
+ count_field_types(select_lex, &curr_join->tmp_table_param,
curr_join->tmp_all_fields1,
curr_join->select_distinct && !curr_join->group_list);
curr_join->tmp_table_param.hidden_field_count=
@@ -1904,11 +1904,13 @@ JOIN::exec()
if (make_simple_join(curr_join, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, curr_join->group_list);
- count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
+ count_field_types(select_lex, &curr_join->tmp_table_param,
+ *curr_all_fields, 0);
}
if (procedure)
- count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
+ count_field_types(select_lex, &curr_join->tmp_table_param,
+ *curr_all_fields, 0);
if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP)))
@@ -13976,8 +13978,8 @@ next_item:
*****************************************************************************/
void
-count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
- bool reset_with_sum_func)
+count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
+ List<Item> &fields, bool reset_with_sum_func)
{
List_iterator<Item> li(fields);
Item *field;
@@ -13995,18 +13997,22 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
if (! field->const_item())
{
Item_sum *sum_item=(Item_sum*) field->real_item();
- if (!sum_item->quick_group)
- param->quick_group=0; // UDF SUM function
- param->sum_func_count++;
- param->func_count++;
+ if (!sum_item->depended_from() ||
+ sum_item->depended_from() == select_lex)
+ {
+ if (!sum_item->quick_group)
+ param->quick_group=0; // UDF SUM function
+ param->sum_func_count++;
- for (uint i=0 ; i < sum_item->arg_count ; i++)
- {
- if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
- param->field_count++;
- else
- param->func_count++;
- }
+ for (uint i=0 ; i < sum_item->arg_count ; i++)
+ {
+ if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
+ param->field_count++;
+ else
+ param->func_count++;
+ }
+ }
+ param->func_count++;
}
}
else
@@ -14467,7 +14473,9 @@ bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
func= sum_funcs;
while ((item=it++))
{
- if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
+ if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
+ (!((Item_sum*) item)->depended_from() ||
+ ((Item_sum *)item)->depended_from() == select_lex))
*func++= (Item_sum*) item;
}
if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
@@ -15049,7 +15057,10 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
ref_array= ref_array_start;
}
- if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
+ if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
+ (!((Item_sum*) item)->depended_from() ||
+ ((Item_sum *)item)->depended_from() == select_lex))
+
{
/*
This is a top level summary function that must be replaced with
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 290a0f5d992..98f2a7829dd 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -509,8 +509,8 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ulonglong select_options, ha_rows rows_limit,
char* alias);
void free_tmp_table(THD *thd, TABLE *entry);
-void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
- bool reset_with_sum_func);
+void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
+ List<Item> &fields, bool reset_with_sum_func);
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
Item **ref_pointer_array,
List<Item> &new_list1, List<Item> &new_list2,
diff --git a/sql/table.cc b/sql/table.cc
index 45ca17afce4..68964e420da 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2221,7 +2221,19 @@ File create_frm(THD *thd, const char *name, const char *db,
ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
fileinfo[4]=1;
int2store(fileinfo+6,IO_SIZE); /* Next block starts here */
- key_length=keys*(7+NAME_LEN+MAX_REF_PARTS*9)+16;
+ /*
+ Keep in sync with pack_keys() in unireg.cc
+ For each key:
+ 8 bytes for the key header
+ 9 bytes for each key-part (MAX_REF_PARTS)
+ NAME_LEN bytes for the name
+ 1 byte for the NAMES_SEP_CHAR (before the name)
+ For all keys:
+ 6 bytes for the header
+ 1 byte for the NAMES_SEP_CHAR (after the last name)
+ 9 extra bytes (padding for safety? alignment?)
+ */
+ key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16;
length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
create_info->extra_size));
int4store(fileinfo+10,length);