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 1fdee50f 0156fd94
...@@ -522,20 +522,50 @@ row_ins_cascade_calc_update_vec( ...@@ -522,20 +522,50 @@ row_ins_cascade_calc_update_vec(
&& ufield->new_val.len && ufield->new_val.len
< dtype_get_fixed_size(type)) { < dtype_get_fixed_size(type)) {
ulint cset;
ufield->new_val.data = ufield->new_val.data =
mem_heap_alloc(heap, mem_heap_alloc(heap,
dtype_get_fixed_size(type)); dtype_get_fixed_size(type));
ufield->new_val.len = ufield->new_val.len =
dtype_get_fixed_size(type); dtype_get_fixed_size(type);
ut_a(dtype_get_pad_char(type)
!= ULINT_UNDEFINED); /* Handle UCS2 strings differently.
As no new collations will be
memset(ufield->new_val.data, introduced in 4.1, we hardcode the
(byte)dtype_get_pad_char(type), charset-collation codes here.
dtype_get_fixed_size(type)); In 5.0, the logic is based on
ut_memcpy(ufield->new_val.data, mbminlen. */
parent_ufield->new_val.data, cset = dtype_get_charset_coll(
parent_ufield->new_val.len); 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; ufield->extern_storage = FALSE;
......
...@@ -108,3 +108,29 @@ select * from t1 procedure analyse (1,1); ...@@ -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 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 test.t1.d 100000 100000 6 6 0 0 100000 0 MEDIUMINT(6) UNSIGNED NOT NULL
drop table t1; 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); ...@@ -57,4 +57,29 @@ insert into t1 values (100000);
select * from t1 procedure analyse (1,1); select * from t1 procedure analyse (1,1);
drop table t1; 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 # End of 4.1 tests
...@@ -1044,18 +1044,21 @@ JOIN::save_join_tab() ...@@ -1044,18 +1044,21 @@ JOIN::save_join_tab()
void void
JOIN::exec() JOIN::exec()
{ {
List<Item> *columns_list= &fields_list;
int tmp_error; int tmp_error;
DBUG_ENTER("JOIN::exec"); DBUG_ENTER("JOIN::exec");
error= 0; error= 0;
if (procedure) if (procedure)
{ {
if (procedure->change_columns(fields_list) || procedure_fields_list= fields_list;
result->prepare(fields_list, unit)) if (procedure->change_columns(procedure_fields_list) ||
result->prepare(procedure_fields_list, unit))
{ {
thd->limit_found_rows= thd->examined_row_count= 0; thd->limit_found_rows= thd->examined_row_count= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
columns_list= &procedure_fields_list;
} }
else if (test(select_options & OPTION_BUFFER_RESULT) && else if (test(select_options & OPTION_BUFFER_RESULT) &&
result && result->prepare(fields_list, unit)) result && result->prepare(fields_list, unit))
...@@ -1072,7 +1075,7 @@ JOIN::exec() ...@@ -1072,7 +1075,7 @@ JOIN::exec()
(zero_result_cause?zero_result_cause:"No tables used")); (zero_result_cause?zero_result_cause:"No tables used"));
else 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 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 even if we don't have any tables for prepared statements or if
...@@ -1082,9 +1085,9 @@ JOIN::exec() ...@@ -1082,9 +1085,9 @@ JOIN::exec()
(!conds || conds->val_int()) && (!conds || conds->val_int()) &&
(!having || having->val_int())) (!having || having->val_int()))
{ {
if (do_send_rows && (procedure ? (procedure->send_row(fields_list) || if (do_send_rows &&
procedure->end_of_records()) (procedure ? (procedure->send_row(procedure_fields_list) ||
: result->send_data(fields_list))) procedure->end_of_records()) : result->send_data(fields_list)))
error= 1; error= 1;
else else
{ {
...@@ -1108,7 +1111,7 @@ JOIN::exec() ...@@ -1108,7 +1111,7 @@ JOIN::exec()
if (zero_result_cause) 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(), send_row_on_empty_set(),
select_options, select_options,
zero_result_cause, zero_result_cause,
...@@ -5845,13 +5848,13 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) ...@@ -5845,13 +5848,13 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
JOIN_TAB *join_tab; JOIN_TAB *join_tab;
int (*end_select)(JOIN *, struct st_join_table *,bool); int (*end_select)(JOIN *, struct st_join_table *,bool);
DBUG_ENTER("do_select"); DBUG_ENTER("do_select");
List<Item> *columns_list= procedure ? &join->procedure_fields_list : fields;
join->procedure=procedure; join->procedure=procedure;
/* /*
Tell the client how many fields there are in a row Tell the client how many fields there are in a row
*/ */
if (!table) if (!table)
join->result->send_fields(*fields,1); join->result->send_fields(*columns_list, 1);
else else
{ {
VOID(table->file->extra(HA_EXTRA_WRITE_CACHE)); VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
...@@ -5913,7 +5916,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) ...@@ -5913,7 +5916,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
error=(*end_select)(join,join_tab,1); error=(*end_select)(join,join_tab,1);
} }
else if (join->send_row_on_empty_set()) else if (join->send_row_on_empty_set())
error= join->result->send_data(*join->fields); error= join->result->send_data(*columns_list);
} }
else else
{ {
...@@ -6612,7 +6615,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -6612,7 +6615,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(0); // Didn't match having DBUG_RETURN(0); // Didn't match having
error=0; error=0;
if (join->procedure) 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) else if (join->do_send_rows)
error=join->result->send_data(*join->fields); error=join->result->send_data(*join->fields);
if (error) if (error)
......
...@@ -204,6 +204,7 @@ class JOIN :public Sql_alloc ...@@ -204,6 +204,7 @@ class JOIN :public Sql_alloc
//Part, shared with list above, emulate following list //Part, shared with list above, emulate following list
List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3; List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
List<Item> &fields_list; // hold field list passed to mysql_select List<Item> &fields_list; // hold field list passed to mysql_select
List<Item> procedure_fields_list;
int error; int error;
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select 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