Commit 9fa6b1e2 authored by unknown's avatar unknown

Merge jamppa@bk-internal.mysql.com:/home/bk/mysql-4.1

into  a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-4.1
parents 78f3127e 537a30d1
......@@ -522,20 +522,50 @@ row_ins_cascade_calc_update_vec(
&& ufield->new_val.len
< dtype_get_fixed_size(type)) {
ulint cset;
ufield->new_val.data =
mem_heap_alloc(heap,
dtype_get_fixed_size(type));
ufield->new_val.len =
dtype_get_fixed_size(type);
ut_a(dtype_get_pad_char(type)
!= ULINT_UNDEFINED);
memset(ufield->new_val.data,
(byte)dtype_get_pad_char(type),
dtype_get_fixed_size(type));
ut_memcpy(ufield->new_val.data,
parent_ufield->new_val.data,
parent_ufield->new_val.len);
/* Handle UCS2 strings differently.
As no new collations will be
introduced in 4.1, we hardcode the
charset-collation codes here.
In 5.0, the logic is based on
mbminlen. */
cset = dtype_get_charset_coll(
dtype_get_prtype(type));
if (cset == 35/*ucs2_general_ci*/
|| cset == 90/*ucs2_bin*/
|| (cset >= 128/*ucs2_unicode_ci*/
&& cset <= 144
/*ucs2_persian_ci*/)) {
/* space=0x0020 */
ulint i;
for (i = 0;
i < ufield->new_val.len;
i += 2) {
mach_write_to_2(((byte*)
ufield->new_val.data)
+ i, 0x0020);
}
} else {
ut_a(dtype_get_pad_char(type)
!= ULINT_UNDEFINED);
memset(ufield->new_val.data,
(byte)dtype_get_pad_char(
type),
ufield->new_val.len);
}
memcpy(ufield->new_val.data,
parent_ufield->new_val.data,
parent_ufield->new_val.len);
}
ufield->extern_storage = FALSE;
......
......@@ -108,3 +108,29 @@ select * from t1 procedure analyse (1,1);
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t1.d 100000 100000 6 6 0 0 100000 0 MEDIUMINT(6) UNSIGNED NOT NULL
drop table t1;
create table t1 (product varchar(32), country_id int not null, year int,
profit int);
insert into t1 values ( 'Computer', 2,2000, 1200),
( 'TV', 1, 1999, 150),
( 'Calculator', 1, 1999,50),
( 'Computer', 1, 1999,1500),
( 'Computer', 1, 2000,1500),
( 'TV', 1, 2000, 150),
( 'TV', 2, 2000, 100),
( 'TV', 2, 2000, 100),
( 'Calculator', 1, 2000,75),
( 'Calculator', 2, 2000,75),
( 'TV', 1, 1999, 100),
( 'Computer', 1, 1999,1200),
( 'Computer', 2, 2000,1500),
( 'Calculator', 2, 2000,75),
( 'Phone', 3, 2003,10)
;
create table t2 (country_id int primary key, country char(20) not null);
insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland');
select product, sum(profit),avg(profit) from t1 group by product with rollup procedure analyse();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t1.product Computer TV 2 8 0 0 4.2500 NULL ENUM('Computer','Phone','TV') NOT NULL
sum(profit) 10 6900 2 4 0 0 1946 2868 ENUM('10','275','600','6900') NOT NULL
avg(profit) 10.0000 1380.0000 7 9 0 0 394.6875 570.2003 ENUM('10.0000','68.7500','120.0000','1380.0000') NOT NULL
drop table t1,t2;
......@@ -57,4 +57,29 @@ insert into t1 values (100000);
select * from t1 procedure analyse (1,1);
drop table t1;
#
# Bug #14138 ROLLUP and PROCEDURE ANALYSE() hang server
#
create table t1 (product varchar(32), country_id int not null, year int,
profit int);
insert into t1 values ( 'Computer', 2,2000, 1200),
( 'TV', 1, 1999, 150),
( 'Calculator', 1, 1999,50),
( 'Computer', 1, 1999,1500),
( 'Computer', 1, 2000,1500),
( 'TV', 1, 2000, 150),
( 'TV', 2, 2000, 100),
( 'TV', 2, 2000, 100),
( 'Calculator', 1, 2000,75),
( 'Calculator', 2, 2000,75),
( 'TV', 1, 1999, 100),
( 'Computer', 1, 1999,1200),
( 'Computer', 2, 2000,1500),
( 'Calculator', 2, 2000,75),
( 'Phone', 3, 2003,10)
;
create table t2 (country_id int primary key, country char(20) not null);
insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland');
select product, sum(profit),avg(profit) from t1 group by product with rollup procedure analyse();
drop table t1,t2;
# End of 4.1 tests
......@@ -1044,18 +1044,21 @@ JOIN::save_join_tab()
void
JOIN::exec()
{
List<Item> *columns_list= &fields_list;
int tmp_error;
DBUG_ENTER("JOIN::exec");
error= 0;
if (procedure)
{
if (procedure->change_columns(fields_list) ||
result->prepare(fields_list, unit))
procedure_fields_list= fields_list;
if (procedure->change_columns(procedure_fields_list) ||
result->prepare(procedure_fields_list, unit))
{
thd->limit_found_rows= thd->examined_row_count= 0;
DBUG_VOID_RETURN;
}
columns_list= &procedure_fields_list;
}
else if (test(select_options & OPTION_BUFFER_RESULT) &&
result && result->prepare(fields_list, unit))
......@@ -1072,7 +1075,7 @@ JOIN::exec()
(zero_result_cause?zero_result_cause:"No tables used"));
else
{
result->send_fields(fields_list,1);
result->send_fields(*columns_list, 1);
/*
We have to test for 'conds' here as the WHERE may not be constant
even if we don't have any tables for prepared statements or if
......@@ -1082,9 +1085,9 @@ JOIN::exec()
(!conds || conds->val_int()) &&
(!having || having->val_int()))
{
if (do_send_rows && (procedure ? (procedure->send_row(fields_list) ||
procedure->end_of_records())
: result->send_data(fields_list)))
if (do_send_rows &&
(procedure ? (procedure->send_row(procedure_fields_list) ||
procedure->end_of_records()) : result->send_data(fields_list)))
error= 1;
else
{
......@@ -1108,7 +1111,7 @@ JOIN::exec()
if (zero_result_cause)
{
(void) return_zero_rows(this, result, tables_list, fields_list,
(void) return_zero_rows(this, result, tables_list, *columns_list,
send_row_on_empty_set(),
select_options,
zero_result_cause,
......@@ -5845,13 +5848,13 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
JOIN_TAB *join_tab;
int (*end_select)(JOIN *, struct st_join_table *,bool);
DBUG_ENTER("do_select");
List<Item> *columns_list= procedure ? &join->procedure_fields_list : fields;
join->procedure=procedure;
/*
Tell the client how many fields there are in a row
*/
if (!table)
join->result->send_fields(*fields,1);
join->result->send_fields(*columns_list, 1);
else
{
VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
......@@ -5913,7 +5916,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
error=(*end_select)(join,join_tab,1);
}
else if (join->send_row_on_empty_set())
error= join->result->send_data(*join->fields);
error= join->result->send_data(*columns_list);
}
else
{
......@@ -6612,7 +6615,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(0); // Didn't match having
error=0;
if (join->procedure)
error=join->procedure->send_row(*join->fields);
error=join->procedure->send_row(join->procedure_fields_list);
else if (join->do_send_rows)
error=join->result->send_data(*join->fields);
if (error)
......
......@@ -204,6 +204,7 @@ class JOIN :public Sql_alloc
//Part, shared with list above, emulate following list
List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
List<Item> &fields_list; // hold field list passed to mysql_select
List<Item> procedure_fields_list;
int error;
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment