Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
3103b4ca
Commit
3103b4ca
authored
Mar 16, 2005
by
igor@rurik.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge rurik.mysql.com:/home/igor/mysql-4.1
into rurik.mysql.com:/home/igor/dev/mysql-4.1-0
parents
155f8ff8
45ba1388
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
211 additions
and
30 deletions
+211
-30
mysql-test/r/olap.result
mysql-test/r/olap.result
+72
-0
mysql-test/t/olap.test
mysql-test/t/olap.test
+30
-0
sql/item.h
sql/item.h
+11
-0
sql/sql_select.cc
sql/sql_select.cc
+96
-29
sql/sql_select.h
sql/sql_select.h
+2
-1
No files found.
mysql-test/r/olap.result
View file @
3103b4ca
...
...
@@ -307,3 +307,75 @@ day sample not_cancelled
2004-06-07 1 0
NULL 3 1
DROP TABLE user_day;
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES
(1,4),
(2,2), (2,2),
(4,1), (4,1), (4,1), (4,1),
(2,1), (2,1);
SELECT SUM(b) FROM t1 GROUP BY a WITH ROLLUP;
SUM(b)
4
6
4
14
SELECT DISTINCT SUM(b) FROM t1 GROUP BY a WITH ROLLUP;
SUM(b)
4
6
14
SELECT SUM(b), COUNT(DISTINCT b) FROM t1 GROUP BY a WITH ROLLUP;
SUM(b) COUNT(DISTINCT b)
4 1
6 2
4 1
14 3
SELECT DISTINCT SUM(b), COUNT(DISTINCT b) FROM t1 GROUP BY a WITH ROLLUP;
SUM(b) COUNT(DISTINCT b)
4 1
6 2
14 3
SELECT SUM(b), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
SUM(b) COUNT(*)
4 1
6 4
4 4
14 9
SELECT DISTINCT SUM(b), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
SUM(b) COUNT(*)
4 1
6 4
4 4
14 9
SELECT SUM(b), COUNT(DISTINCT b), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
SUM(b) COUNT(DISTINCT b) COUNT(*)
4 1 1
6 2 4
4 1 4
14 3 9
SELECT DISTINCT SUM(b), COUNT(DISTINCT b), COUNT(*) FROM t1
GROUP BY a WITH ROLLUP;
SUM(b) COUNT(DISTINCT b) COUNT(*)
4 1 1
6 2 4
4 1 4
14 3 9
SELECT a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
a sum(b)
1 4
1 4
2 2
2 4
2 6
4 4
4 4
NULL 14
SELECT DISTINCT a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
a sum(b)
1 4
2 2
2 4
2 6
4 4
NULL 14
DROP TABLE t1;
mysql-test/t/olap.test
View file @
3103b4ca
...
...
@@ -125,3 +125,33 @@ SELECT
DROP
TABLE
user_day
;
#
# Tests for bugs #8616, #8615: distinct sum with rollup
#
CREATE
TABLE
t1
(
a
int
,
b
int
);
INSERT
INTO
t1
VALUES
(
1
,
4
),
(
2
,
2
),
(
2
,
2
),
(
4
,
1
),
(
4
,
1
),
(
4
,
1
),
(
4
,
1
),
(
2
,
1
),
(
2
,
1
);
SELECT
SUM
(
b
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
DISTINCT
SUM
(
b
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
SUM
(
b
),
COUNT
(
DISTINCT
b
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
DISTINCT
SUM
(
b
),
COUNT
(
DISTINCT
b
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
SUM
(
b
),
COUNT
(
*
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
DISTINCT
SUM
(
b
),
COUNT
(
*
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
SUM
(
b
),
COUNT
(
DISTINCT
b
),
COUNT
(
*
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
DISTINCT
SUM
(
b
),
COUNT
(
DISTINCT
b
),
COUNT
(
*
)
FROM
t1
GROUP
BY
a
WITH
ROLLUP
;
SELECT
a
,
sum
(
b
)
FROM
t1
GROUP
BY
a
,
b
WITH
ROLLUP
;
SELECT
DISTINCT
a
,
sum
(
b
)
FROM
t1
GROUP
BY
a
,
b
WITH
ROLLUP
;
DROP
TABLE
t1
;
sql/item.h
View file @
3103b4ca
...
...
@@ -470,6 +470,17 @@ public:
Item
*
safe_charset_converter
(
CHARSET_INFO
*
tocs
);
};
class
Item_null_result
:
public
Item_null
{
public:
Field
*
result_field
;
Item_null_result
()
:
Item_null
(),
result_field
(
0
)
{}
bool
is_result_field
()
{
return
result_field
!=
0
;
}
void
save_in_result_field
(
bool
no_conversions
)
{
save_in_field
(
result_field
,
no_conversions
);
}
};
/* Item represents one placeholder ('?') of prepared statement */
...
...
sql/sql_select.cc
View file @
3103b4ca
...
...
@@ -157,7 +157,7 @@ static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
uint
elements
,
List
<
Item
>
&
items
);
static
void
init_tmptable_sum_functions
(
Item_sum
**
func
);
static
void
update_tmptable_sum_func
(
Item_sum
**
func
,
TABLE
*
tmp_table
);
static
void
copy_sum_funcs
(
Item_sum
**
func_ptr
);
static
void
copy_sum_funcs
(
Item_sum
**
func_ptr
,
Item_sum
**
end
);
static
bool
add_ref_to_table_cond
(
THD
*
thd
,
JOIN_TAB
*
join_tab
);
static
bool
init_sum_functions
(
Item_sum
**
func
,
Item_sum
**
end
);
static
bool
update_sum_func
(
Item_sum
**
func
);
...
...
@@ -1269,7 +1269,6 @@ JOIN::exec()
{
DBUG_VOID_RETURN
;
}
curr_join
->
group_list
=
0
;
}
thd
->
proc_info
=
"Copying to group table"
;
...
...
@@ -1289,8 +1288,10 @@ JOIN::exec()
}
}
if
(
curr_join
->
make_sum_func_list
(
*
curr_all_fields
,
*
curr_fields_list
,
1
)
||
(
tmp_error
=
do_select
(
curr_join
,
(
List
<
Item
>
*
)
0
,
curr_tmp_table
,
1
))
DBUG_VOID_RETURN
;
curr_join
->
group_list
=
0
;
if
((
tmp_error
=
do_select
(
curr_join
,
(
List
<
Item
>
*
)
0
,
curr_tmp_table
,
0
)))
{
error
=
tmp_error
;
...
...
@@ -1328,7 +1329,7 @@ JOIN::exec()
if
(
curr_join
->
tmp_having
)
curr_join
->
tmp_having
->
update_used_tables
();
if
(
remove_duplicates
(
curr_join
,
curr_tmp_table
,
curr_join
->
fields_list
,
curr_join
->
tmp_having
))
*
curr_
fields_list
,
curr_join
->
tmp_having
))
DBUG_VOID_RETURN
;
curr_join
->
tmp_having
=
0
;
curr_join
->
select_distinct
=
0
;
...
...
@@ -6740,26 +6741,32 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if
(
join
->
procedure
)
join
->
procedure
->
end_group
();
if
(
idx
<
(
int
)
join
->
send_group_parts
)
int
send_group_parts
=
join
->
send_group_parts
;
if
(
idx
<
send_group_parts
)
{
if
(
!
join
->
first_record
)
{
/* No matching rows for group function */
join
->
clear
();
}
copy_sum_funcs
(
join
->
sum_funcs
);
if
(
!
join
->
having
||
join
->
having
->
val_int
())
{
if
((
error
=
table
->
file
->
write_row
(
table
->
record
[
0
])))
copy_sum_funcs
(
join
->
sum_funcs
,
join
->
sum_funcs_end
[
send_group_parts
]);
if
(
join
->
having
&&
join
->
having
->
val_int
()
==
0
)
error
=
-
1
;
else
if
((
error
=
table
->
file
->
write_row
(
table
->
record
[
0
])))
{
if
(
create_myisam_from_heap
(
join
->
thd
,
table
,
&
join
->
tmp_table_param
,
error
,
0
))
DBUG_RETURN
(
-
1
);
// Not a table_is_full error
DBUG_RETURN
(
-
1
);
}
else
join
->
send_records
++
;
if
(
join
->
rollup
.
state
!=
ROLLUP
::
STATE_NONE
&&
error
<=
0
)
{
if
(
join
->
rollup_write_data
((
uint
)
(
idx
+
1
),
table
))
error
=
1
;
}
if
(
error
>
0
)
DBUG_RETURN
(
-
1
);
if
(
end_of_records
)
DBUG_RETURN
(
0
);
}
...
...
@@ -8888,11 +8895,10 @@ update_tmptable_sum_func(Item_sum **func_ptr,
/* Copy result of sum functions to record in tmp_table */
static
void
copy_sum_funcs
(
Item_sum
**
func_ptr
)
copy_sum_funcs
(
Item_sum
**
func_ptr
,
Item_sum
**
end_ptr
)
{
Item_sum
*
func
;
for
(;
(
func
=
*
func_ptr
)
;
func_ptr
++
)
(
void
)
func
->
save_in_result_field
(
1
);
for
(;
func_ptr
!=
end_ptr
;
func_ptr
++
)
(
void
)
(
*
func_ptr
)
->
save_in_result_field
(
1
);
return
;
}
...
...
@@ -9013,14 +9019,16 @@ bool JOIN::rollup_init()
*/
tmp_table_param
.
group_parts
=
send_group_parts
;
if
(
!
(
rollup
.
fields
=
(
List
<
Item
>*
)
thd
->
alloc
((
sizeof
(
Item
*
)
+
if
(
!
(
rollup
.
null_items
=
(
Item_null_result
**
)
thd
->
alloc
((
sizeof
(
Item
*
)
+
sizeof
(
Item
**
)
+
sizeof
(
List
<
Item
>
)
+
ref_pointer_array_size
)
*
send_group_parts
)))
*
send_group_parts
)))
return
1
;
rollup
.
fields
=
(
List
<
Item
>*
)
(
rollup
.
null_items
+
send_group_parts
);
rollup
.
ref_pointer_arrays
=
(
Item
***
)
(
rollup
.
fields
+
send_group_parts
);
ref_array
=
(
Item
**
)
(
rollup
.
ref_pointer_arrays
+
send_group_parts
);
rollup
.
item_null
=
new
(
thd
->
mem_root
)
Item_null
();
/*
Prepare space for field list for the different levels
...
...
@@ -9028,12 +9036,16 @@ bool JOIN::rollup_init()
*/
for
(
i
=
0
;
i
<
send_group_parts
;
i
++
)
{
rollup
.
null_items
[
i
]
=
new
(
thd
->
mem_root
)
Item_null_result
();
List
<
Item
>
*
rollup_fields
=
&
rollup
.
fields
[
i
];
rollup_fields
->
empty
();
rollup
.
ref_pointer_arrays
[
i
]
=
ref_array
;
ref_array
+=
all_fields
.
elements
;
}
for
(
i
=
0
;
i
<
send_group_parts
;
i
++
)
{
for
(
j
=
0
;
j
<
fields_list
.
elements
;
j
++
)
rollup
_fields
->
push_back
(
rollup
.
item_null
);
rollup
.
fields
[
i
].
push_back
(
rollup
.
null_items
[
i
]
);
}
return
0
;
}
...
...
@@ -9137,7 +9149,8 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
{
/* Check if this is something that is part of this group by */
ORDER
*
group_tmp
;
for
(
group_tmp
=
start_group
;
group_tmp
;
group_tmp
=
group_tmp
->
next
)
for
(
group_tmp
=
start_group
,
i
--
;
group_tmp
;
group_tmp
=
group_tmp
->
next
,
i
++
)
{
if
(
*
group_tmp
->
item
==
item
)
{
...
...
@@ -9146,7 +9159,9 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
set to NULL in this level
*/
item
->
maybe_null
=
1
;
// Value will be null sometimes
item
=
rollup
.
item_null
;
Item_null_result
*
null_item
=
rollup
.
null_items
[
i
];
null_item
->
result_field
=
((
Item_field
*
)
item
)
->
result_field
;
item
=
null_item
;
break
;
}
}
...
...
@@ -9206,6 +9221,58 @@ int JOIN::rollup_send_data(uint idx)
return
0
;
}
/*
Write all rollup levels higher than the current one to a temp table
SYNOPSIS:
rollup_write_data()
idx Level we are on:
0 = Total sum level
1 = First group changed (a)
2 = Second group changed (a,b)
table reference to temp table
SAMPLE
SELECT a, b, SUM(c) FROM t1 GROUP BY a,b WITH ROLLUP
RETURN
0 ok
1 if write_data_failed()
*/
int
JOIN
::
rollup_write_data
(
uint
idx
,
TABLE
*
table
)
{
uint
i
;
for
(
i
=
send_group_parts
;
i
--
>
idx
;
)
{
/* Get reference pointers to sum functions in place */
memcpy
((
char
*
)
ref_pointer_array
,
(
char
*
)
rollup
.
ref_pointer_arrays
[
i
],
ref_pointer_array_size
);
if
((
!
having
||
having
->
val_int
()))
{
int
error
;
Item
*
item
;
List_iterator_fast
<
Item
>
it
(
rollup
.
fields
[
i
]);
while
((
item
=
it
++
))
{
if
(
item
->
type
()
==
Item
::
NULL_ITEM
&&
item
->
is_result_field
())
item
->
save_in_result_field
(
1
);
}
copy_sum_funcs
(
sum_funcs_end
[
i
+
1
],
sum_funcs_end
[
i
]);
if
((
error
=
table
->
file
->
write_row
(
table
->
record
[
0
])))
{
if
(
create_myisam_from_heap
(
thd
,
table
,
&
tmp_table_param
,
error
,
0
))
return
1
;
}
}
}
/* Restore ref_pointer_array */
set_items_ref_array
(
current_ref_pointer_array
);
return
0
;
}
/*
clear results if there are not rows found for group
(end_send_group/end_write_group)
...
...
sql/sql_select.h
View file @
3103b4ca
...
...
@@ -124,7 +124,7 @@ typedef struct st_rollup
{
enum
State
{
STATE_NONE
,
STATE_INITED
,
STATE_READY
};
State
state
;
Item
*
item_null
;
Item
_null_result
**
null_items
;
Item
***
ref_pointer_arrays
;
List
<
Item
>
*
fields
;
}
ROLLUP
;
...
...
@@ -295,6 +295,7 @@ class JOIN :public Sql_alloc
bool
rollup_make_fields
(
List
<
Item
>
&
all_fields
,
List
<
Item
>
&
fields
,
Item_sum
***
func
);
int
rollup_send_data
(
uint
idx
);
int
rollup_write_data
(
uint
idx
,
TABLE
*
table
);
bool
test_in_subselect
(
Item
**
where
);
void
join_free
(
bool
full
);
void
clear
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment