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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
3847b1b2
Commit
3847b1b2
authored
Nov 10, 2007
by
tnurnberg@white.intern.koehntopp.de
Browse files
Options
Browse Files
Download
Plain Diff
Merge tnurnberg@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into mysql.com:/misc/mysql/31700/50-31700
parents
4c1ff7b5
8b21045f
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
244 additions
and
17 deletions
+244
-17
mysql-test/r/group_by.result
mysql-test/r/group_by.result
+65
-0
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+49
-0
mysql-test/t/group_by.test
mysql-test/t/group_by.test
+35
-0
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+42
-0
sql/item.cc
sql/item.cc
+12
-4
sql/item.h
sql/item.h
+11
-3
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+1
-1
sql/item_subselect.cc
sql/item_subselect.cc
+12
-1
sql/sp_rcontext.cc
sql/sp_rcontext.cc
+3
-3
sql/sp_rcontext.h
sql/sp_rcontext.h
+1
-1
sql/sql_class.cc
sql/sql_class.cc
+1
-1
sql/sql_select.cc
sql/sql_select.cc
+12
-3
No files found.
mysql-test/r/group_by.result
View file @
3847b1b2
...
...
@@ -1113,3 +1113,68 @@ c b
3 1
3 2
DROP TABLE t1;
CREATE TABLE t1(
id INT AUTO_INCREMENT PRIMARY KEY,
c1 INT NOT NULL,
c2 INT NOT NULL,
UNIQUE KEY (c2,c1));
INSERT INTO t1(c1,c2) VALUES (5,1), (4,1), (3,5), (2,3), (1,3);
SELECT * FROM t1 ORDER BY c1;
id c1 c2
5 1 3
4 2 3
3 3 5
2 4 1
1 5 1
SELECT * FROM t1 GROUP BY id ORDER BY c1;
id c1 c2
5 1 3
4 2 3
3 3 5
2 4 1
1 5 1
SELECT * FROM t1 GROUP BY id ORDER BY id DESC;
id c1 c2
5 1 3
4 2 3
3 3 5
2 4 1
1 5 1
SELECT * FROM t1 GROUP BY c2 ,c1, id ORDER BY c2, c1;
id c1 c2
2 4 1
1 5 1
5 1 3
4 2 3
3 3 5
SELECT * FROM t1 GROUP BY c2, c1, id ORDER BY c2 DESC, c1;
id c1 c2
3 3 5
5 1 3
4 2 3
2 4 1
1 5 1
SELECT * FROM t1 GROUP BY c2, c1, id ORDER BY c2 DESC, c1 DESC;
id c1 c2
3 3 5
4 2 3
5 1 3
1 5 1
2 4 1
SELECT * FROM t1 GROUP BY c2 ORDER BY c2, c1;
id c1 c2
1 5 1
4 2 3
3 3 5
SELECT * FROM t1 GROUP BY c2 ORDER BY c2 DESC, c1;
id c1 c2
3 3 5
4 2 3
1 5 1
SELECT * FROM t1 GROUP BY c2 ORDER BY c2 DESC, c1 DESC;
id c1 c2
3 3 5
4 2 3
1 5 1
DROP TABLE t1;
End of 5.0 tests
mysql-test/r/subselect.result
View file @
3847b1b2
...
...
@@ -4150,4 +4150,53 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
0
0
DROP TABLE t1, t2;
CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
s1 s2
SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
s1 s2
CREATE INDEX I1 ON t1 (s1);
CREATE INDEX I2 ON t1 (s2);
SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
s1 s2
SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
s1 s2
TRUNCATE t1;
INSERT INTO t1 VALUES (0x41,0x41);
SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
s1 s2
DROP TABLE t1;
CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
CREATE TABLE t3 (a3 BINARY(2) default '0');
INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (1),(2),(3);
INSERT INTO t3 VALUES (1),(2),(3);
SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
LEFT(t2.a2, 1)
1
2
3
SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
1 0
2 0
3 0
4 0
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
INSERT INTO t2 VALUES (2), (3), (4), (5);
INSERT INTO t3 VALUES (10), (20), (30);
SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
LEFT(t1.a1,1)
1
2
3
SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
a2
DROP TABLE t1, t2, t3;
End of 5.0 tests.
mysql-test/t/group_by.test
View file @
3847b1b2
...
...
@@ -815,3 +815,38 @@ EXPLAIN SELECT c,b FROM t1 GROUP BY c,b;
SELECT
c
,
b
FROM
t1
GROUP
BY
c
,
b
;
DROP
TABLE
t1
;
#
# Bug #32202: ORDER BY not working with GROUP BY
#
CREATE
TABLE
t1
(
id
INT
AUTO_INCREMENT
PRIMARY
KEY
,
c1
INT
NOT
NULL
,
c2
INT
NOT
NULL
,
UNIQUE
KEY
(
c2
,
c1
));
INSERT
INTO
t1
(
c1
,
c2
)
VALUES
(
5
,
1
),
(
4
,
1
),
(
3
,
5
),
(
2
,
3
),
(
1
,
3
);
# Show that the test cases from the bug report pass
SELECT
*
FROM
t1
ORDER
BY
c1
;
SELECT
*
FROM
t1
GROUP
BY
id
ORDER
BY
c1
;
# Show that DESC is handled correctly
SELECT
*
FROM
t1
GROUP
BY
id
ORDER
BY
id
DESC
;
# Show that results are correctly ordered when ORDER BY fields
# are a subset of GROUP BY ones
SELECT
*
FROM
t1
GROUP
BY
c2
,
c1
,
id
ORDER
BY
c2
,
c1
;
SELECT
*
FROM
t1
GROUP
BY
c2
,
c1
,
id
ORDER
BY
c2
DESC
,
c1
;
SELECT
*
FROM
t1
GROUP
BY
c2
,
c1
,
id
ORDER
BY
c2
DESC
,
c1
DESC
;
# Show that results are correctly ordered when GROUP BY fields
# are a subset of ORDER BY ones
SELECT
*
FROM
t1
GROUP
BY
c2
ORDER
BY
c2
,
c1
;
SELECT
*
FROM
t1
GROUP
BY
c2
ORDER
BY
c2
DESC
,
c1
;
SELECT
*
FROM
t1
GROUP
BY
c2
ORDER
BY
c2
DESC
,
c1
DESC
;
DROP
TABLE
t1
;
--
echo
End
of
5.0
tests
mysql-test/t/subselect.test
View file @
3847b1b2
...
...
@@ -3002,4 +3002,46 @@ INSERT INTO t2 VALUES (103, 203);
SELECT
((
a1
,
a2
)
IN
(
SELECT
*
FROM
t2
WHERE
b2
>
0
))
IS
NULL
FROM
t1
;
DROP
TABLE
t1
,
t2
;
#
# Bug #28076: inconsistent binary/varbinary comparison
#
CREATE
TABLE
t1
(
s1
BINARY
(
5
),
s2
VARBINARY
(
5
));
INSERT
INTO
t1
VALUES
(
0x41
,
0x41
),
(
0x42
,
0x42
),
(
0x43
,
0x43
);
SELECT
s1
,
s2
FROM
t1
WHERE
s2
IN
(
SELECT
s1
FROM
t1
);
SELECT
s1
,
s2
FROM
t1
WHERE
(
s2
,
10
)
IN
(
SELECT
s1
,
10
FROM
t1
);
CREATE
INDEX
I1
ON
t1
(
s1
);
CREATE
INDEX
I2
ON
t1
(
s2
);
SELECT
s1
,
s2
FROM
t1
WHERE
s2
IN
(
SELECT
s1
FROM
t1
);
SELECT
s1
,
s2
FROM
t1
WHERE
(
s2
,
10
)
IN
(
SELECT
s1
,
10
FROM
t1
);
TRUNCATE
t1
;
INSERT
INTO
t1
VALUES
(
0x41
,
0x41
);
SELECT
*
FROM
t1
WHERE
s1
=
(
SELECT
s2
FROM
t1
);
DROP
TABLE
t1
;
CREATE
TABLE
t1
(
a1
VARBINARY
(
2
)
NOT
NULL
DEFAULT
'0'
,
PRIMARY
KEY
(
a1
));
CREATE
TABLE
t2
(
a2
BINARY
(
2
)
default
'0'
,
INDEX
(
a2
));
CREATE
TABLE
t3
(
a3
BINARY
(
2
)
default
'0'
);
INSERT
INTO
t1
VALUES
(
1
),(
2
),(
3
),(
4
);
INSERT
INTO
t2
VALUES
(
1
),(
2
),(
3
);
INSERT
INTO
t3
VALUES
(
1
),(
2
),(
3
);
SELECT
LEFT
(
t2
.
a2
,
1
)
FROM
t2
,
t3
WHERE
t3
.
a3
=
t2
.
a2
;
SELECT
t1
.
a1
,
t1
.
a1
in
(
SELECT
t2
.
a2
FROM
t2
,
t3
WHERE
t3
.
a3
=
t2
.
a2
)
FROM
t1
;
DROP
TABLE
t1
,
t2
,
t3
;
CREATE
TABLE
t1
(
a1
BINARY
(
3
)
PRIMARY
KEY
,
b1
VARBINARY
(
3
));
CREATE
TABLE
t2
(
a2
VARBINARY
(
3
)
PRIMARY
KEY
);
CREATE
TABLE
t3
(
a3
VARBINARY
(
3
)
PRIMARY
KEY
);
INSERT
INTO
t1
VALUES
(
1
,
10
),
(
2
,
20
),
(
3
,
30
),
(
4
,
40
);
INSERT
INTO
t2
VALUES
(
2
),
(
3
),
(
4
),
(
5
);
INSERT
INTO
t3
VALUES
(
10
),
(
20
),
(
30
);
SELECT
LEFT
(
t1
.
a1
,
1
)
FROM
t1
,
t3
WHERE
t1
.
b1
=
t3
.
a3
;
SELECT
a2
FROM
t2
WHERE
t2
.
a2
IN
(
SELECT
t1
.
a1
FROM
t1
,
t3
WHERE
t1
.
b1
=
t3
.
a3
);
DROP
TABLE
t1
,
t2
,
t3
;
--
echo
End
of
5.0
tests
.
sql/item.cc
View file @
3847b1b2
...
...
@@ -6259,9 +6259,9 @@ bool field_is_equal_to_item(Field *field,Item *item)
return
result
==
field
->
val_real
();
}
Item_cache
*
Item_cache
::
get_cache
(
Item_result
type
)
Item_cache
*
Item_cache
::
get_cache
(
const
Item
*
item
)
{
switch
(
type
)
{
switch
(
item
->
result_type
()
)
{
case
INT_RESULT
:
return
new
Item_cache_int
();
case
REAL_RESULT
:
...
...
@@ -6269,7 +6269,7 @@ Item_cache* Item_cache::get_cache(Item_result type)
case
DECIMAL_RESULT
:
return
new
Item_cache_decimal
();
case
STRING_RESULT
:
return
new
Item_cache_str
();
return
new
Item_cache_str
(
item
);
case
ROW_RESULT
:
return
new
Item_cache_row
();
default:
...
...
@@ -6447,6 +6447,14 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
}
int
Item_cache_str
::
save_in_field
(
Field
*
field
,
bool
no_conversions
)
{
int
res
=
Item_cache
::
save_in_field
(
field
,
no_conversions
);
return
(
is_varbinary
&&
field
->
type
()
==
MYSQL_TYPE_STRING
&&
value
->
length
()
<
field
->
field_length
)
?
1
:
res
;
}
bool
Item_cache_row
::
allocate
(
uint
num
)
{
item_count
=
num
;
...
...
@@ -6465,7 +6473,7 @@ bool Item_cache_row::setup(Item * item)
{
Item
*
el
=
item
->
element_index
(
i
);
Item_cache
*
tmp
;
if
(
!
(
tmp
=
values
[
i
]
=
Item_cache
::
get_cache
(
el
->
result_type
()
)))
if
(
!
(
tmp
=
values
[
i
]
=
Item_cache
::
get_cache
(
el
)))
return
1
;
tmp
->
setup
(
el
);
}
...
...
sql/item.h
View file @
3847b1b2
...
...
@@ -2469,7 +2469,7 @@ class Item_cache: public Item
};
virtual
void
store
(
Item
*
)
=
0
;
enum
Type
type
()
const
{
return
CACHE_ITEM
;
}
static
Item_cache
*
get_cache
(
Item_result
type
);
static
Item_cache
*
get_cache
(
const
Item
*
item
);
table_map
used_tables
()
const
{
return
used_table_map
;
}
virtual
void
keep_array
()
{}
// to prevent drop fixed flag (no need parent cleanup call)
...
...
@@ -2531,9 +2531,16 @@ class Item_cache_str: public Item_cache
{
char
buffer
[
STRING_BUFFER_USUAL_SIZE
];
String
*
value
,
value_buff
;
bool
is_varbinary
;
public:
Item_cache_str
()
:
Item_cache
(),
value
(
0
)
{
}
Item_cache_str
(
const
Item
*
item
)
:
Item_cache
(),
value
(
0
),
is_varbinary
(
item
->
type
()
==
FIELD_ITEM
&&
((
const
Item_field
*
)
item
)
->
field
->
type
()
==
MYSQL_TYPE_VARCHAR
&&
!
((
const
Item_field
*
)
item
)
->
field
->
has_charset
())
{}
void
store
(
Item
*
item
);
double
val_real
();
longlong
val_int
();
...
...
@@ -2541,6 +2548,7 @@ class Item_cache_str: public Item_cache
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
CHARSET_INFO
*
charset
()
const
{
return
value
->
charset
();
};
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
};
class
Item_cache_row
:
public
Item_cache
...
...
sql/item_cmpfunc.cc
View file @
3847b1b2
...
...
@@ -1386,7 +1386,7 @@ longlong Item_func_truth::val_int()
bool
Item_in_optimizer
::
fix_left
(
THD
*
thd
,
Item
**
ref
)
{
if
(
!
args
[
0
]
->
fixed
&&
args
[
0
]
->
fix_fields
(
thd
,
args
)
||
!
cache
&&
!
(
cache
=
Item_cache
::
get_cache
(
args
[
0
]
->
result_type
()
)))
!
cache
&&
!
(
cache
=
Item_cache
::
get_cache
(
args
[
0
])))
return
1
;
cache
->
setup
(
args
[
0
]);
...
...
sql/item_subselect.cc
View file @
3847b1b2
...
...
@@ -1717,7 +1717,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
item
->
decimals
=
sel_item
->
decimals
;
item
->
unsigned_flag
=
sel_item
->
unsigned_flag
;
maybe_null
=
sel_item
->
maybe_null
;
if
(
!
(
row
[
i
]
=
Item_cache
::
get_cache
(
res_type
)))
if
(
!
(
row
[
i
]
=
Item_cache
::
get_cache
(
sel_item
)))
return
;
row
[
i
]
->
setup
(
sel_item
);
}
...
...
@@ -2178,6 +2178,7 @@ int subselect_indexsubquery_engine::exec()
((
Item_in_subselect
*
)
item
)
->
value
=
0
;
empty_result_set
=
TRUE
;
null_keypart
=
0
;
table
->
status
=
0
;
if
(
check_null
)
{
...
...
@@ -2190,6 +2191,16 @@ int subselect_indexsubquery_engine::exec()
if
(
copy_ref_key
())
DBUG_RETURN
(
1
);
if
(
table
->
status
)
{
/*
We know that there will be no rows even if we scan.
Can be set in copy_ref_key.
*/
((
Item_in_subselect
*
)
item
)
->
value
=
0
;
DBUG_RETURN
(
0
);
}
if
(
null_keypart
)
DBUG_RETURN
(
scan_table
());
...
...
sql/sp_rcontext.cc
View file @
3847b1b2
...
...
@@ -503,14 +503,14 @@ sp_cursor::fetch(THD *thd, List<struct sp_variable> *vars)
*/
Item_cache
*
sp_rcontext
::
create_case_expr_holder
(
THD
*
thd
,
Item_result
result_type
)
sp_rcontext
::
create_case_expr_holder
(
THD
*
thd
,
const
Item
*
item
)
{
Item_cache
*
holder
;
Query_arena
current_arena
;
thd
->
set_n_backup_active_arena
(
thd
->
spcont
->
callers_arena
,
&
current_arena
);
holder
=
Item_cache
::
get_cache
(
result_type
);
holder
=
Item_cache
::
get_cache
(
item
);
thd
->
restore_active_arena
(
thd
->
spcont
->
callers_arena
,
&
current_arena
);
...
...
@@ -559,7 +559,7 @@ sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr
case_expr_item
->
result_type
())
{
m_case_expr_holders
[
case_expr_id
]
=
create_case_expr_holder
(
thd
,
case_expr_item
->
result_type
()
);
create_case_expr_holder
(
thd
,
case_expr_item
);
}
m_case_expr_holders
[
case_expr_id
]
->
store
(
case_expr_item
);
...
...
sql/sp_rcontext.h
View file @
3847b1b2
...
...
@@ -261,7 +261,7 @@ class sp_rcontext : public Sql_alloc
bool
init_var_table
(
THD
*
thd
);
bool
init_var_items
();
Item_cache
*
create_case_expr_holder
(
THD
*
thd
,
Item_result
result_type
);
Item_cache
*
create_case_expr_holder
(
THD
*
thd
,
const
Item
*
item
);
int
set_variable
(
THD
*
thd
,
Field
*
field
,
Item
**
value
);
};
// class sp_rcontext : public Sql_alloc
...
...
sql/sql_class.cc
View file @
3847b1b2
...
...
@@ -1553,7 +1553,7 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items)
{
if
(
!
cache
)
{
cache
=
Item_cache
::
get_cache
(
val_item
->
result_type
()
);
cache
=
Item_cache
::
get_cache
(
val_item
);
switch
(
val_item
->
result_type
())
{
case
REAL_RESULT
:
...
...
sql/sql_select.cc
View file @
3847b1b2
...
...
@@ -1065,10 +1065,19 @@ JOIN::optimize()
We have found that grouping can be removed since groups correspond to
only one row anyway, but we still have to guarantee correct result
order. The line below effectively rewrites the query from GROUP BY
<fields> to ORDER BY <fields>. One exception is if skip_sort_order is
set (see above), then we can simply skip GROUP BY.
<fields> to ORDER BY <fields>. There are two exceptions:
- if skip_sort_order is set (see above), then we can simply skip
GROUP BY;
- we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
with the GROUP BY ones, i.e. either one is a prefix of another.
We only check if the ORDER BY is a prefix of GROUP BY. In this case
test_if_subpart() copies the ASC/DESC attributes from the original
ORDER BY fields.
If GROUP BY is a prefix of ORDER BY, then it is safe to leave
'order' as is.
*/
order
=
skip_sort_order
?
0
:
group_list
;
if
(
!
order
||
test_if_subpart
(
group_list
,
order
))
order
=
skip_sort_order
?
0
:
group_list
;
group_list
=
0
;
group
=
0
;
}
...
...
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